Merge pull request #4926 from rokups/rk/misc-fixes

Two fixes
This commit is contained in:
Matthias 2021-05-15 15:11:07 +02:00 committed by GitHub
commit 4f968b4a6f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 33 additions and 9 deletions

View File

@ -9,7 +9,7 @@ from copy import deepcopy
from datetime import datetime, timedelta, timezone from datetime import datetime, timedelta, timezone
from typing import Any, Dict, List, Optional, Tuple from typing import Any, Dict, List, Optional, Tuple
from pandas import DataFrame, NaT from pandas import DataFrame
from freqtrade.configuration import TimeRange, remove_credentials, validate_config_consistency from freqtrade.configuration import TimeRange, remove_credentials, validate_config_consistency
from freqtrade.constants import DATETIME_PRINT_FORMAT from freqtrade.constants import DATETIME_PRINT_FORMAT
@ -115,8 +115,6 @@ class Backtesting:
# Get maximum required startup period # Get maximum required startup period
self.required_startup = max([strat.startup_candle_count for strat in self.strategylist]) self.required_startup = max([strat.startup_candle_count for strat in self.strategylist])
# Load one (first) strategy
self._set_strategy(self.strategylist[0])
def __del__(self): def __del__(self):
LoggingMixin.show_output = True LoggingMixin.show_output = True
@ -457,13 +455,21 @@ class Backtesting:
preprocessed = self.strategy.ohlcvdata_to_dataframe(data) preprocessed = self.strategy.ohlcvdata_to_dataframe(data)
# Trim startup period from analyzed dataframe # Trim startup period from analyzed dataframe
for pair, df in preprocessed.items(): for pair in list(preprocessed):
preprocessed[pair] = trim_dataframe(df, timerange, df = preprocessed[pair]
startup_candles=self.required_startup) df = trim_dataframe(df, timerange, startup_candles=self.required_startup)
min_date, max_date = history.get_timerange(preprocessed) if len(df) > 0:
if min_date is NaT or max_date is NaT: preprocessed[pair] = df
else:
logger.warning(f'{pair} has no data left after adjusting for startup candles, '
f'skipping.')
del preprocessed[pair]
if not preprocessed:
raise OperationalException( raise OperationalException(
"No data left after adjusting for startup candles.") "No data left after adjusting for startup candles.")
min_date, max_date = history.get_timerange(preprocessed)
logger.info(f'Backtesting with data from {min_date.strftime(DATETIME_PRINT_FORMAT)} ' logger.info(f'Backtesting with data from {min_date.strftime(DATETIME_PRINT_FORMAT)} '
f'up to {max_date.strftime(DATETIME_PRINT_FORMAT)} ' f'up to {max_date.strftime(DATETIME_PRINT_FORMAT)} '
f'({(max_date - min_date).days} days).') f'({(max_date - min_date).days} days).')

View File

@ -79,6 +79,7 @@ class Hyperopt:
self.custom_hyperopt = HyperOptAuto(self.config) self.custom_hyperopt = HyperOptAuto(self.config)
else: else:
self.custom_hyperopt = HyperOptResolver.load_hyperopt(self.config) self.custom_hyperopt = HyperOptResolver.load_hyperopt(self.config)
self.backtesting._set_strategy(self.backtesting.strategylist[0])
self.custom_hyperopt.strategy = self.backtesting.strategy self.custom_hyperopt.strategy = self.backtesting.strategy
self.custom_hyperoptloss = HyperOptLossResolver.load_hyperoptloss(self.config) self.custom_hyperoptloss = HyperOptLossResolver.load_hyperoptloss(self.config)

View File

@ -493,6 +493,7 @@ def test_backtest_results(default_conf, fee, mocker, caplog, data) -> None:
patch_exchange(mocker) patch_exchange(mocker)
frame = _build_backtest_dataframe(data.data) frame = _build_backtest_dataframe(data.data)
backtesting = Backtesting(default_conf) backtesting = Backtesting(default_conf)
backtesting._set_strategy(backtesting.strategylist[0])
backtesting.strategy.advise_buy = lambda a, m: frame backtesting.strategy.advise_buy = lambda a, m: frame
backtesting.strategy.advise_sell = lambda a, m: frame backtesting.strategy.advise_sell = lambda a, m: frame
caplog.set_level(logging.DEBUG) caplog.set_level(logging.DEBUG)

View File

@ -83,6 +83,7 @@ def simple_backtest(config, contour, mocker, testdatadir) -> None:
patch_exchange(mocker) patch_exchange(mocker)
config['timeframe'] = '1m' config['timeframe'] = '1m'
backtesting = Backtesting(config) backtesting = Backtesting(config)
backtesting._set_strategy(backtesting.strategylist[0])
data = load_data_test(contour, testdatadir) data = load_data_test(contour, testdatadir)
processed = backtesting.strategy.ohlcvdata_to_dataframe(data) processed = backtesting.strategy.ohlcvdata_to_dataframe(data)
@ -106,6 +107,7 @@ def _make_backtest_conf(mocker, datadir, conf=None, pair='UNITTEST/BTC'):
data = trim_dictlist(data, -201) data = trim_dictlist(data, -201)
patch_exchange(mocker) patch_exchange(mocker)
backtesting = Backtesting(conf) backtesting = Backtesting(conf)
backtesting._set_strategy(backtesting.strategylist[0])
processed = backtesting.strategy.ohlcvdata_to_dataframe(data) processed = backtesting.strategy.ohlcvdata_to_dataframe(data)
min_date, max_date = get_timerange(processed) min_date, max_date = get_timerange(processed)
return { return {
@ -285,6 +287,7 @@ def test_backtesting_init(mocker, default_conf, order_types) -> None:
patch_exchange(mocker) patch_exchange(mocker)
get_fee = mocker.patch('freqtrade.exchange.Exchange.get_fee', MagicMock(return_value=0.5)) get_fee = mocker.patch('freqtrade.exchange.Exchange.get_fee', MagicMock(return_value=0.5))
backtesting = Backtesting(default_conf) backtesting = Backtesting(default_conf)
backtesting._set_strategy(backtesting.strategylist[0])
assert backtesting.config == default_conf assert backtesting.config == default_conf
assert backtesting.timeframe == '5m' assert backtesting.timeframe == '5m'
assert callable(backtesting.strategy.ohlcvdata_to_dataframe) assert callable(backtesting.strategy.ohlcvdata_to_dataframe)
@ -315,11 +318,13 @@ def test_data_with_fee(default_conf, mocker, testdatadir) -> None:
fee_mock = mocker.patch('freqtrade.exchange.Exchange.get_fee', MagicMock(return_value=0.5)) fee_mock = mocker.patch('freqtrade.exchange.Exchange.get_fee', MagicMock(return_value=0.5))
backtesting = Backtesting(default_conf) backtesting = Backtesting(default_conf)
backtesting._set_strategy(backtesting.strategylist[0])
assert backtesting.fee == 0.1234 assert backtesting.fee == 0.1234
assert fee_mock.call_count == 0 assert fee_mock.call_count == 0
default_conf['fee'] = 0.0 default_conf['fee'] = 0.0
backtesting = Backtesting(default_conf) backtesting = Backtesting(default_conf)
backtesting._set_strategy(backtesting.strategylist[0])
assert backtesting.fee == 0.0 assert backtesting.fee == 0.0
assert fee_mock.call_count == 0 assert fee_mock.call_count == 0
@ -330,6 +335,7 @@ def test_data_to_dataframe_bt(default_conf, mocker, testdatadir) -> None:
data = history.load_data(testdatadir, '1m', ['UNITTEST/BTC'], timerange=timerange, data = history.load_data(testdatadir, '1m', ['UNITTEST/BTC'], timerange=timerange,
fill_up_missing=True) fill_up_missing=True)
backtesting = Backtesting(default_conf) backtesting = Backtesting(default_conf)
backtesting._set_strategy(backtesting.strategylist[0])
processed = backtesting.strategy.ohlcvdata_to_dataframe(data) processed = backtesting.strategy.ohlcvdata_to_dataframe(data)
assert len(processed['UNITTEST/BTC']) == 102 assert len(processed['UNITTEST/BTC']) == 102
@ -361,6 +367,7 @@ def test_backtesting_start(default_conf, mocker, testdatadir, caplog) -> None:
default_conf['timerange'] = '-1510694220' default_conf['timerange'] = '-1510694220'
backtesting = Backtesting(default_conf) backtesting = Backtesting(default_conf)
backtesting._set_strategy(backtesting.strategylist[0])
backtesting.strategy.bot_loop_start = MagicMock() backtesting.strategy.bot_loop_start = MagicMock()
backtesting.start() backtesting.start()
# check the logs, that will contain the backtest result # check the logs, that will contain the backtest result
@ -393,6 +400,7 @@ def test_backtesting_start_no_data(default_conf, mocker, caplog, testdatadir) ->
default_conf['timerange'] = '20180101-20180102' default_conf['timerange'] = '20180101-20180102'
backtesting = Backtesting(default_conf) backtesting = Backtesting(default_conf)
backtesting._set_strategy(backtesting.strategylist[0])
with pytest.raises(OperationalException, match='No data found. Terminating.'): with pytest.raises(OperationalException, match='No data found. Terminating.'):
backtesting.start() backtesting.start()
@ -465,6 +473,7 @@ def test_backtest__enter_trade(default_conf, fee, mocker) -> None:
default_conf['stake_amount'] = 'unlimited' default_conf['stake_amount'] = 'unlimited'
default_conf['max_open_trades'] = 2 default_conf['max_open_trades'] = 2
backtesting = Backtesting(default_conf) backtesting = Backtesting(default_conf)
backtesting._set_strategy(backtesting.strategylist[0])
pair = 'UNITTEST/BTC' pair = 'UNITTEST/BTC'
row = [ row = [
pd.Timestamp(year=2020, month=1, day=1, hour=5, minute=0), pd.Timestamp(year=2020, month=1, day=1, hour=5, minute=0),
@ -508,6 +517,7 @@ def test_backtest_one(default_conf, fee, mocker, testdatadir) -> None:
mocker.patch("freqtrade.exchange.Exchange.get_min_pair_stake_amount", return_value=0.00001) mocker.patch("freqtrade.exchange.Exchange.get_min_pair_stake_amount", return_value=0.00001)
patch_exchange(mocker) patch_exchange(mocker)
backtesting = Backtesting(default_conf) backtesting = Backtesting(default_conf)
backtesting._set_strategy(backtesting.strategylist[0])
pair = 'UNITTEST/BTC' pair = 'UNITTEST/BTC'
timerange = TimeRange('date', None, 1517227800, 0) timerange = TimeRange('date', None, 1517227800, 0)
data = history.load_data(datadir=testdatadir, timeframe='5m', pairs=['UNITTEST/BTC'], data = history.load_data(datadir=testdatadir, timeframe='5m', pairs=['UNITTEST/BTC'],
@ -570,6 +580,7 @@ def test_backtest_1min_timeframe(default_conf, fee, mocker, testdatadir) -> None
mocker.patch("freqtrade.exchange.Exchange.get_min_pair_stake_amount", return_value=0.00001) mocker.patch("freqtrade.exchange.Exchange.get_min_pair_stake_amount", return_value=0.00001)
patch_exchange(mocker) patch_exchange(mocker)
backtesting = Backtesting(default_conf) backtesting = Backtesting(default_conf)
backtesting._set_strategy(backtesting.strategylist[0])
# Run a backtesting for an exiting 1min timeframe # Run a backtesting for an exiting 1min timeframe
timerange = TimeRange.parse_timerange('1510688220-1510700340') timerange = TimeRange.parse_timerange('1510688220-1510700340')
@ -591,6 +602,7 @@ def test_backtest_1min_timeframe(default_conf, fee, mocker, testdatadir) -> None
def test_processed(default_conf, mocker, testdatadir) -> None: def test_processed(default_conf, mocker, testdatadir) -> None:
patch_exchange(mocker) patch_exchange(mocker)
backtesting = Backtesting(default_conf) backtesting = Backtesting(default_conf)
backtesting._set_strategy(backtesting.strategylist[0])
dict_of_tickerrows = load_data_test('raise', testdatadir) dict_of_tickerrows = load_data_test('raise', testdatadir)
dataframes = backtesting.strategy.ohlcvdata_to_dataframe(dict_of_tickerrows) dataframes = backtesting.strategy.ohlcvdata_to_dataframe(dict_of_tickerrows)
@ -661,6 +673,7 @@ def test_backtest_clash_buy_sell(mocker, default_conf, testdatadir):
backtest_conf = _make_backtest_conf(mocker, conf=default_conf, datadir=testdatadir) backtest_conf = _make_backtest_conf(mocker, conf=default_conf, datadir=testdatadir)
backtesting = Backtesting(default_conf) backtesting = Backtesting(default_conf)
backtesting._set_strategy(backtesting.strategylist[0])
backtesting.strategy.advise_buy = fun # Override backtesting.strategy.advise_buy = fun # Override
backtesting.strategy.advise_sell = fun # Override backtesting.strategy.advise_sell = fun # Override
result = backtesting.backtest(**backtest_conf) result = backtesting.backtest(**backtest_conf)
@ -676,6 +689,7 @@ def test_backtest_only_sell(mocker, default_conf, testdatadir):
backtest_conf = _make_backtest_conf(mocker, conf=default_conf, datadir=testdatadir) backtest_conf = _make_backtest_conf(mocker, conf=default_conf, datadir=testdatadir)
backtesting = Backtesting(default_conf) backtesting = Backtesting(default_conf)
backtesting._set_strategy(backtesting.strategylist[0])
backtesting.strategy.advise_buy = fun # Override backtesting.strategy.advise_buy = fun # Override
backtesting.strategy.advise_sell = fun # Override backtesting.strategy.advise_sell = fun # Override
result = backtesting.backtest(**backtest_conf) result = backtesting.backtest(**backtest_conf)
@ -689,6 +703,7 @@ def test_backtest_alternate_buy_sell(default_conf, fee, mocker, testdatadir):
pair='UNITTEST/BTC', datadir=testdatadir) pair='UNITTEST/BTC', datadir=testdatadir)
default_conf['timeframe'] = '1m' default_conf['timeframe'] = '1m'
backtesting = Backtesting(default_conf) backtesting = Backtesting(default_conf)
backtesting._set_strategy(backtesting.strategylist[0])
backtesting.strategy.advise_buy = _trend_alternate # Override backtesting.strategy.advise_buy = _trend_alternate # Override
backtesting.strategy.advise_sell = _trend_alternate # Override backtesting.strategy.advise_sell = _trend_alternate # Override
result = backtesting.backtest(**backtest_conf) result = backtesting.backtest(**backtest_conf)
@ -731,6 +746,7 @@ def test_backtest_multi_pair(default_conf, fee, mocker, tres, pair, testdatadir)
default_conf['timeframe'] = '5m' default_conf['timeframe'] = '5m'
backtesting = Backtesting(default_conf) backtesting = Backtesting(default_conf)
backtesting._set_strategy(backtesting.strategylist[0])
backtesting.strategy.advise_buy = _trend_alternate_hold # Override backtesting.strategy.advise_buy = _trend_alternate_hold # Override
backtesting.strategy.advise_sell = _trend_alternate_hold # Override backtesting.strategy.advise_sell = _trend_alternate_hold # Override