2022-08-13 08:48:57 +00:00
|
|
|
from copy import deepcopy
|
|
|
|
from datetime import datetime, timezone
|
2022-08-13 07:10:03 +00:00
|
|
|
from pathlib import Path
|
2022-08-13 09:07:58 +00:00
|
|
|
from unittest.mock import PropertyMock
|
2022-08-13 07:10:03 +00:00
|
|
|
|
2022-09-26 22:01:24 +00:00
|
|
|
import pytest
|
|
|
|
|
2022-09-24 11:21:01 +00:00
|
|
|
from freqtrade.commands.optimize_commands import setup_optimize_configuration
|
2023-12-19 17:14:02 +00:00
|
|
|
from freqtrade.configuration.timerange import TimeRange
|
|
|
|
from freqtrade.data import history
|
|
|
|
from freqtrade.data.dataprovider import DataProvider
|
2022-09-24 11:21:01 +00:00
|
|
|
from freqtrade.enums import RunMode
|
2023-12-19 17:14:02 +00:00
|
|
|
from freqtrade.enums.candletype import CandleType
|
2022-09-26 22:01:24 +00:00
|
|
|
from freqtrade.exceptions import OperationalException
|
2023-12-19 17:14:02 +00:00
|
|
|
from freqtrade.freqai.data_kitchen import FreqaiDataKitchen
|
2022-08-13 08:48:57 +00:00
|
|
|
from freqtrade.optimize.backtesting import Backtesting
|
2024-05-12 13:08:40 +00:00
|
|
|
from tests.conftest import (
|
|
|
|
CURRENT_TEST_STRATEGY,
|
|
|
|
get_args,
|
|
|
|
get_patched_exchange,
|
|
|
|
log_has_re,
|
|
|
|
patch_exchange,
|
|
|
|
patched_configuration_load_config_file,
|
|
|
|
)
|
2023-12-19 17:14:02 +00:00
|
|
|
from tests.freqai.conftest import get_patched_freqai_strategy
|
2022-08-13 07:10:03 +00:00
|
|
|
|
|
|
|
|
2022-09-24 11:21:01 +00:00
|
|
|
def test_freqai_backtest_start_backtest_list(freqai_conf, mocker, testdatadir, caplog):
|
2022-08-13 07:10:03 +00:00
|
|
|
patch_exchange(mocker)
|
|
|
|
|
2022-09-24 11:21:01 +00:00
|
|
|
now = datetime.now(timezone.utc)
|
2024-05-12 14:02:21 +00:00
|
|
|
mocker.patch(
|
|
|
|
"freqtrade.plugins.pairlistmanager.PairListManager.whitelist",
|
|
|
|
PropertyMock(return_value=["HULUMULU/USDT", "XRP/USDT"]),
|
|
|
|
)
|
|
|
|
mocker.patch("freqtrade.optimize.backtesting.history.load_data")
|
|
|
|
mocker.patch("freqtrade.optimize.backtesting.history.get_timerange", return_value=(now, now))
|
2022-08-13 07:10:03 +00:00
|
|
|
|
|
|
|
patched_configuration_load_config_file(mocker, freqai_conf)
|
|
|
|
|
|
|
|
args = [
|
2024-05-12 14:02:21 +00:00
|
|
|
"backtesting",
|
|
|
|
"--config",
|
|
|
|
"config.json",
|
|
|
|
"--datadir",
|
|
|
|
str(testdatadir),
|
|
|
|
"--strategy-path",
|
|
|
|
str(Path(__file__).parents[1] / "strategy/strats"),
|
|
|
|
"--timeframe",
|
|
|
|
"1m",
|
|
|
|
"--strategy-list",
|
|
|
|
CURRENT_TEST_STRATEGY,
|
2022-08-13 07:10:03 +00:00
|
|
|
]
|
|
|
|
args = get_args(args)
|
2022-09-24 11:21:01 +00:00
|
|
|
bt_config = setup_optimize_configuration(args, RunMode.BACKTEST)
|
|
|
|
Backtesting(bt_config)
|
2024-05-12 14:02:21 +00:00
|
|
|
assert log_has_re(
|
|
|
|
"Using --strategy-list with FreqAI REQUIRES all strategies to have identical", caplog
|
|
|
|
)
|
2022-09-24 11:21:01 +00:00
|
|
|
Backtesting.cleanup()
|
2022-08-13 08:48:57 +00:00
|
|
|
|
|
|
|
|
2023-12-19 17:14:02 +00:00
|
|
|
@pytest.mark.parametrize(
|
|
|
|
"timeframe, expected_startup_candle_count",
|
|
|
|
[
|
|
|
|
("5m", 876),
|
|
|
|
("15m", 492),
|
|
|
|
("1d", 302),
|
|
|
|
],
|
|
|
|
)
|
2024-05-12 14:02:21 +00:00
|
|
|
def test_freqai_backtest_load_data(
|
|
|
|
freqai_conf, mocker, caplog, timeframe, expected_startup_candle_count
|
|
|
|
):
|
2022-08-13 08:48:57 +00:00
|
|
|
patch_exchange(mocker)
|
|
|
|
|
|
|
|
now = datetime.now(timezone.utc)
|
2024-05-12 14:02:21 +00:00
|
|
|
mocker.patch(
|
|
|
|
"freqtrade.plugins.pairlistmanager.PairListManager.whitelist",
|
|
|
|
PropertyMock(return_value=["HULUMULU/USDT", "XRP/USDT"]),
|
|
|
|
)
|
|
|
|
mocker.patch("freqtrade.optimize.backtesting.history.load_data")
|
|
|
|
mocker.patch("freqtrade.optimize.backtesting.history.get_timerange", return_value=(now, now))
|
|
|
|
freqai_conf["timeframe"] = timeframe
|
|
|
|
freqai_conf.get("freqai", {}).get("feature_parameters", {}).update({"include_timeframes": []})
|
2022-08-13 08:48:57 +00:00
|
|
|
backtesting = Backtesting(deepcopy(freqai_conf))
|
|
|
|
backtesting.load_bt_data()
|
|
|
|
|
2024-05-12 14:02:21 +00:00
|
|
|
assert log_has_re(
|
|
|
|
f"Increasing startup_candle_count for freqai on {timeframe} "
|
|
|
|
f"to {expected_startup_candle_count}",
|
|
|
|
caplog,
|
|
|
|
)
|
|
|
|
assert history.load_data.call_args[1]["startup_candles"] == expected_startup_candle_count
|
2022-08-13 08:48:57 +00:00
|
|
|
|
|
|
|
Backtesting.cleanup()
|
2022-09-26 22:01:24 +00:00
|
|
|
|
|
|
|
|
|
|
|
def test_freqai_backtest_live_models_model_not_found(freqai_conf, mocker, testdatadir, caplog):
|
|
|
|
patch_exchange(mocker)
|
|
|
|
|
|
|
|
now = datetime.now(timezone.utc)
|
2024-05-12 14:02:21 +00:00
|
|
|
mocker.patch(
|
|
|
|
"freqtrade.plugins.pairlistmanager.PairListManager.whitelist",
|
|
|
|
PropertyMock(return_value=["HULUMULU/USDT", "XRP/USDT"]),
|
|
|
|
)
|
|
|
|
mocker.patch("freqtrade.optimize.backtesting.history.load_data")
|
|
|
|
mocker.patch("freqtrade.optimize.backtesting.history.get_timerange", return_value=(now, now))
|
2022-09-26 22:01:24 +00:00
|
|
|
freqai_conf["timerange"] = ""
|
2022-11-20 01:27:58 +00:00
|
|
|
freqai_conf.get("freqai", {}).update({"backtest_using_historic_predictions": False})
|
|
|
|
|
2022-09-26 22:01:24 +00:00
|
|
|
patched_configuration_load_config_file(mocker, freqai_conf)
|
|
|
|
|
|
|
|
args = [
|
2024-05-12 14:02:21 +00:00
|
|
|
"backtesting",
|
|
|
|
"--config",
|
|
|
|
"config.json",
|
|
|
|
"--datadir",
|
|
|
|
str(testdatadir),
|
|
|
|
"--strategy-path",
|
|
|
|
str(Path(__file__).parents[1] / "strategy/strats"),
|
|
|
|
"--timeframe",
|
|
|
|
"5m",
|
|
|
|
"--freqai-backtest-live-models",
|
2022-09-26 22:01:24 +00:00
|
|
|
]
|
|
|
|
args = get_args(args)
|
|
|
|
bt_config = setup_optimize_configuration(args, RunMode.BACKTEST)
|
|
|
|
|
2024-05-12 14:02:21 +00:00
|
|
|
with pytest.raises(
|
|
|
|
OperationalException, match=r".* Historic predictions data is required to run backtest .*"
|
|
|
|
):
|
2022-09-26 22:01:24 +00:00
|
|
|
Backtesting(bt_config)
|
|
|
|
|
|
|
|
Backtesting.cleanup()
|
2023-12-19 17:14:02 +00:00
|
|
|
|
|
|
|
|
|
|
|
def test_freqai_backtest_consistent_timerange(mocker, freqai_conf):
|
2024-05-12 14:02:21 +00:00
|
|
|
freqai_conf["runmode"] = "backtest"
|
|
|
|
mocker.patch(
|
|
|
|
"freqtrade.plugins.pairlistmanager.PairListManager.whitelist",
|
|
|
|
PropertyMock(return_value=["XRP/USDT:USDT"]),
|
|
|
|
)
|
2023-12-19 17:14:02 +00:00
|
|
|
|
2024-05-12 14:02:21 +00:00
|
|
|
gbs = mocker.patch("freqtrade.optimize.backtesting.generate_backtest_stats")
|
2023-12-19 17:14:02 +00:00
|
|
|
|
2024-05-12 14:02:21 +00:00
|
|
|
freqai_conf["candle_type_def"] = CandleType.FUTURES
|
|
|
|
freqai_conf.get("exchange", {}).update({"pair_whitelist": ["XRP/USDT:USDT"]})
|
|
|
|
freqai_conf.get("freqai", {}).get("feature_parameters", {}).update(
|
|
|
|
{"include_timeframes": ["5m", "1h"], "include_corr_pairlist": []}
|
|
|
|
)
|
|
|
|
freqai_conf["timerange"] = "20211120-20211121"
|
2023-12-19 17:14:02 +00:00
|
|
|
|
|
|
|
strategy = get_patched_freqai_strategy(mocker, freqai_conf)
|
|
|
|
exchange = get_patched_exchange(mocker, freqai_conf)
|
|
|
|
|
|
|
|
strategy.dp = DataProvider(freqai_conf, exchange)
|
|
|
|
strategy.freqai_info = freqai_conf.get("freqai", {})
|
|
|
|
freqai = strategy.freqai
|
|
|
|
freqai.dk = FreqaiDataKitchen(freqai_conf)
|
|
|
|
|
|
|
|
timerange = TimeRange.parse_timerange("20211115-20211122")
|
|
|
|
freqai.dd.load_all_pair_histories(timerange, freqai.dk)
|
|
|
|
|
|
|
|
backtesting = Backtesting(deepcopy(freqai_conf))
|
|
|
|
backtesting.start()
|
|
|
|
|
2024-05-12 14:02:21 +00:00
|
|
|
assert gbs.call_args[1]["min_date"] == datetime(2021, 11, 20, 0, 0, tzinfo=timezone.utc)
|
|
|
|
assert gbs.call_args[1]["max_date"] == datetime(2021, 11, 21, 0, 0, tzinfo=timezone.utc)
|
2023-12-31 15:15:18 +00:00
|
|
|
Backtesting.cleanup()
|