diff --git a/config_examples/config_freqai-rl.example.json b/config_examples/config_freqai-rl.example.json deleted file mode 100644 index 9dfea932d..000000000 --- a/config_examples/config_freqai-rl.example.json +++ /dev/null @@ -1,109 +0,0 @@ -{ - "trading_mode": "futures", - "new_pairs_days": 30, - "margin_mode": "isolated", - "max_open_trades": 8, - "stake_currency": "USDT", - "stake_amount": 1000, - "tradable_balance_ratio": 1, - "fiat_display_currency": "USD", - "dry_run": true, - "timeframe": "5m", - "dataformat_ohlcv": "json", - "dry_run_wallet": 12000, - "cancel_open_orders_on_exit": true, - "unfilledtimeout": { - "entry": 10, - "exit": 30 - }, - "exchange": { - "name": "binance", - "key": "", - "secret": "", - "ccxt_config": { - "enableRateLimit": true - }, - "ccxt_async_config": { - "enableRateLimit": true, - "rateLimit": 200 - }, - "pair_whitelist": [ - "1INCH/USDT", - "AAVE/USDT" - ], - "pair_blacklist": [] - }, - "entry_pricing": { - "price_side": "same", - "use_order_book": true, - "order_book_top": 1, - "price_last_balance": 0.0, - "check_depth_of_market": { - "enabled": false, - "bids_to_ask_delta": 1 - } - }, - "exit_pricing": { - "price_side": "other", - "use_order_book": true, - "order_book_top": 1 - }, - "pairlists": [ - { - "method": "StaticPairList" - } - ], - "freqai": { - "enabled": true, - "model_save_type": "stable_baselines", - "conv_width": 4, - "purge_old_models": true, - "limit_ram_usage": false, - "train_period_days": 5, - "backtest_period_days": 2, - "identifier": "unique-id", - "continual_learning": false, - "data_kitchen_thread_count": 2, - "feature_parameters": { - "include_corr_pairlist": [ - "BTC/USDT", - "ETH/USDT" - ], - "include_timeframes": [ - "5m", - "30m" - ], - "indicator_max_period_candles": 20, - "indicator_periods_candles": [14] - }, - "data_split_parameters": { - "test_size": 0.5, - "random_state": 1, - "shuffle": false - }, - "model_training_parameters": { - "learning_rate": 0.00025, - "gamma": 0.9, - "verbose": 1 - }, - "rl_config": { - "train_cycles": 6, - "thread_count": 4, - "max_trade_duration_candles": 300, - "model_type": "PPO", - "policy_type": "MlpPolicy", - "max_training_drawdown_pct": 0.5, - "model_reward_parameters": { - "rr": 1, - "profit_aim": 0.02, - "win_reward_factor": 2 - } - } - }, - "bot_name": "RL_test", - "force_entry_enable": true, - "initial_state": "running", - "internals": { - "process_throttle_secs": 5 - } -} diff --git a/freqtrade/freqai/data_drawer.py b/freqtrade/freqai/data_drawer.py index b58bed9ba..03840317f 100644 --- a/freqtrade/freqai/data_drawer.py +++ b/freqtrade/freqai/data_drawer.py @@ -602,22 +602,3 @@ class FreqaiDataDrawer: ) return corr_dataframes, base_dataframes - - # to be used if we want to send predictions directly to the follower instead of forcing - # follower to load models and inference - # def save_model_return_values_to_disk(self) -> None: - # with open(self.full_path / str('model_return_values.json'), "w") as fp: - # json.dump(self.model_return_values, fp, default=self.np_encoder) - - # def load_model_return_values_from_disk(self, dk: FreqaiDataKitchen) -> FreqaiDataKitchen: - # exists = Path(self.full_path / str('model_return_values.json')).resolve().exists() - # if exists: - # with open(self.full_path / str('model_return_values.json'), "r") as fp: - # self.model_return_values = json.load(fp) - # elif not self.follow_mode: - # logger.info("Could not find existing datadrawer, starting from scratch") - # else: - # logger.warning(f'Follower could not find pair_dictionary at {self.full_path} ' - # 'sending null values back to strategy') - - # return exists, dk diff --git a/tests/freqai/test_freqai_interface.py b/tests/freqai/test_freqai_interface.py index ac8fd2b42..f0af90f18 100644 --- a/tests/freqai/test_freqai_interface.py +++ b/tests/freqai/test_freqai_interface.py @@ -4,13 +4,15 @@ from pathlib import Path from unittest.mock import MagicMock import pytest - +from freqtrade.enums import RunMode from freqtrade.configuration import TimeRange from freqtrade.data.dataprovider import DataProvider from freqtrade.freqai.data_kitchen import FreqaiDataKitchen from freqtrade.plugins.pairlistmanager import PairListManager from tests.conftest import get_patched_exchange, log_has_re from tests.freqai.conftest import get_patched_freqai_strategy +from freqtrade.persistence import Trade +from freqtrade.freqai.utils import download_all_data_for_training, get_required_data_timerange def is_arm() -> bool: @@ -173,29 +175,34 @@ def test_extract_data_and_train_model_Classifiers(mocker, freqai_conf, model): shutil.rmtree(Path(freqai.dk.full_path)) -@pytest.mark.parametrize('model', [ - 'LightGBMRegressor', - 'XGBoostRegressor', - 'CatboostRegressor', - 'ReinforcementLearner' - ]) -def test_start_backtesting(mocker, freqai_conf, model): +@pytest.mark.parametrize( + "model, num_files, strat", + [ + ("LightGBMRegressor", 6, "freqai_test_strat"), + ("XGBoostRegressor", 6, "freqai_test_strat"), + ("CatboostRegressor", 6, "freqai_test_strat"), + ("ReinforcementLearner", 7, "freqai_rl_test_strat"), + ("XGBoostClassifier", 6, "freqai_test_classifier"), + ("LightGBMClassifier", 6, "freqai_test_classifier"), + ("CatboostClassifier", 6, "freqai_test_classifier") + ], + ) +def test_start_backtesting(mocker, freqai_conf, model, num_files, strat): freqai_conf.get("freqai", {}).update({"save_backtest_models": True}) - - if is_arm() and model == 'CatboostRegressor': + freqai_conf['runmode'] = RunMode.BACKTEST + Trade.use_db = False + if is_arm() and "Catboost" in model: pytest.skip("CatBoost is not supported on ARM") if is_mac(): pytest.skip("Reinforcement learning module not available on intel based Mac OS") - model_save_ext = 'joblib' freqai_conf.update({"freqaimodel": model}) - freqai_conf.update({"timerange": "20180110-20180130"}) - freqai_conf.update({"strategy": "freqai_test_strat"}) + freqai_conf.update({"timerange": "20180120-20180130"}) + freqai_conf.update({"strategy": strat}) if 'ReinforcementLearner' in model: - model_save_ext = 'zip' - freqai_conf.update({"strategy": "freqai_rl_test_strat"}) + freqai_conf["freqai"].update({"model_training_parameters": { "learning_rate": 0.00025, "gamma": 0.9, @@ -217,8 +224,7 @@ def test_start_backtesting(mocker, freqai_conf, model): if 'test_4ac' in model: freqai_conf["freqaimodel_path"] = str(Path(__file__).parents[1] / "freqai" / "test_models") - - + strategy = get_patched_freqai_strategy(mocker, freqai_conf) exchange = get_patched_exchange(mocker, freqai_conf) strategy.dp = DataProvider(freqai_conf, exchange) @@ -237,7 +243,7 @@ def test_start_backtesting(mocker, freqai_conf, model): freqai.start_backtesting(df, metadata, freqai.dk) model_folders = [x for x in freqai.dd.full_path.iterdir() if x.is_dir()] - assert len(model_folders) == 6 + assert len(model_folders) == num_files shutil.rmtree(Path(freqai.dk.full_path)) @@ -455,3 +461,40 @@ def test_freqai_informative_pairs(mocker, freqai_conf, timeframes, corr_pairs): pairs_b = strategy.gather_informative_pairs() # we expect unique pairs * timeframes assert len(pairs_b) == len(set(pairlist + corr_pairs)) * len(timeframes) + + +def test_start_set_train_queue(mocker, freqai_conf, caplog): + strategy = get_patched_freqai_strategy(mocker, freqai_conf) + exchange = get_patched_exchange(mocker, freqai_conf) + pairlist = PairListManager(exchange, freqai_conf) + strategy.dp = DataProvider(freqai_conf, exchange, pairlist) + strategy.freqai_info = freqai_conf.get("freqai", {}) + freqai = strategy.freqai + freqai.live = False + + freqai.train_queue = freqai._set_train_queue() + + assert log_has_re( + "Set fresh train queue from whitelist.", + caplog, + ) + + +def test_get_required_data_timerange(mocker, freqai_conf): + time_range = get_required_data_timerange(freqai_conf) + assert (time_range.stopts - time_range.startts) == 177300 + + +def test_download_all_data_for_training(mocker, freqai_conf, caplog, tmpdir): + strategy = get_patched_freqai_strategy(mocker, freqai_conf) + exchange = get_patched_exchange(mocker, freqai_conf) + pairlist = PairListManager(exchange, freqai_conf) + strategy.dp = DataProvider(freqai_conf, exchange, pairlist) + freqai_conf['pairs'] = freqai_conf['exchange']['pair_whitelist'] + freqai_conf['datadir'] = Path(tmpdir) + download_all_data_for_training(strategy.dp, freqai_conf) + + assert log_has_re( + "Downloading", + caplog, + )