Implement better strategy checks

part of #2696
This commit is contained in:
Matthias 2021-06-19 19:32:29 +02:00
parent 39b876e37a
commit 96fbb226c5
2 changed files with 27 additions and 6 deletions

View File

@ -453,18 +453,25 @@ class IStrategy(ABC, HyperStrategyMixin):
""" """
Ensure dataframe (length, last candle) was not modified, and has all elements we need. Ensure dataframe (length, last candle) was not modified, and has all elements we need.
""" """
message_template = "Dataframe returned from strategy has mismatching {}."
message = "" message = ""
if df_len != len(dataframe): if dataframe is None:
message = "length" message = "No dataframe returned (return statement missing?)."
elif 'buy' not in dataframe:
message = "Buy column not set."
elif 'sell' not in dataframe:
message = "Sell column not set."
elif df_len != len(dataframe):
message = message_template.format("length")
elif df_close != dataframe["close"].iloc[-1]: elif df_close != dataframe["close"].iloc[-1]:
message = "last close price" message = message_template.format("last close price")
elif df_date != dataframe["date"].iloc[-1]: elif df_date != dataframe["date"].iloc[-1]:
message = "last date" message = message_template.format("last date")
if message: if message:
if self.disable_dataframe_checks: if self.disable_dataframe_checks:
logger.warning(f"Dataframe returned from strategy has mismatching {message}.") logger.warning(message)
else: else:
raise StrategyError(f"Dataframe returned from strategy has mismatching {message}.") raise StrategyError(message)
def get_signal(self, pair: str, timeframe: str, dataframe: DataFrame) -> Tuple[bool, bool]: def get_signal(self, pair: str, timeframe: str, dataframe: DataFrame) -> Tuple[bool, bool]:
""" """

View File

@ -153,6 +153,8 @@ def test_assert_df_raise(mocker, caplog, ohlcv_history):
def test_assert_df(ohlcv_history, caplog): def test_assert_df(ohlcv_history, caplog):
df_len = len(ohlcv_history) - 1 df_len = len(ohlcv_history) - 1
ohlcv_history.loc[:, 'buy'] = 0
ohlcv_history.loc[:, 'sell'] = 0
# Ensure it's running when passed correctly # Ensure it's running when passed correctly
_STRATEGY.assert_df(ohlcv_history, len(ohlcv_history), _STRATEGY.assert_df(ohlcv_history, len(ohlcv_history),
ohlcv_history.loc[df_len, 'close'], ohlcv_history.loc[df_len, 'date']) ohlcv_history.loc[df_len, 'close'], ohlcv_history.loc[df_len, 'date'])
@ -170,6 +172,18 @@ def test_assert_df(ohlcv_history, caplog):
match=r"Dataframe returned from strategy.*last date\."): match=r"Dataframe returned from strategy.*last date\."):
_STRATEGY.assert_df(ohlcv_history, len(ohlcv_history), _STRATEGY.assert_df(ohlcv_history, len(ohlcv_history),
ohlcv_history.loc[df_len, 'close'], ohlcv_history.loc[0, 'date']) ohlcv_history.loc[df_len, 'close'], ohlcv_history.loc[0, 'date'])
with pytest.raises(StrategyError,
match=r"No dataframe returned \(return statement missing\?\)."):
_STRATEGY.assert_df(None, len(ohlcv_history),
ohlcv_history.loc[df_len, 'close'], ohlcv_history.loc[0, 'date'])
with pytest.raises(StrategyError,
match="Buy column not set"):
_STRATEGY.assert_df(ohlcv_history.drop('buy', axis=1), len(ohlcv_history),
ohlcv_history.loc[df_len, 'close'], ohlcv_history.loc[0, 'date'])
with pytest.raises(StrategyError,
match="Sell column not set"):
_STRATEGY.assert_df(ohlcv_history.drop('sell', axis=1), len(ohlcv_history),
ohlcv_history.loc[df_len, 'close'], ohlcv_history.loc[0, 'date'])
_STRATEGY.disable_dataframe_checks = True _STRATEGY.disable_dataframe_checks = True
caplog.clear() caplog.clear()