increase test coverage for RL and FreqAI

This commit is contained in:
robcaulk 2022-09-23 18:04:43 +02:00
parent 95121550ef
commit 9c361f4422
3 changed files with 61 additions and 146 deletions

View File

@ -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
}
}

View File

@ -602,22 +602,3 @@ class FreqaiDataDrawer:
) )
return corr_dataframes, base_dataframes 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

View File

@ -4,13 +4,15 @@ from pathlib import Path
from unittest.mock import MagicMock from unittest.mock import MagicMock
import pytest import pytest
from freqtrade.enums import RunMode
from freqtrade.configuration import TimeRange from freqtrade.configuration import TimeRange
from freqtrade.data.dataprovider import DataProvider from freqtrade.data.dataprovider import DataProvider
from freqtrade.freqai.data_kitchen import FreqaiDataKitchen from freqtrade.freqai.data_kitchen import FreqaiDataKitchen
from freqtrade.plugins.pairlistmanager import PairListManager from freqtrade.plugins.pairlistmanager import PairListManager
from tests.conftest import get_patched_exchange, log_has_re from tests.conftest import get_patched_exchange, log_has_re
from tests.freqai.conftest import get_patched_freqai_strategy 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: 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)) shutil.rmtree(Path(freqai.dk.full_path))
@pytest.mark.parametrize('model', [ @pytest.mark.parametrize(
'LightGBMRegressor', "model, num_files, strat",
'XGBoostRegressor', [
'CatboostRegressor', ("LightGBMRegressor", 6, "freqai_test_strat"),
'ReinforcementLearner' ("XGBoostRegressor", 6, "freqai_test_strat"),
]) ("CatboostRegressor", 6, "freqai_test_strat"),
def test_start_backtesting(mocker, freqai_conf, model): ("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}) freqai_conf.get("freqai", {}).update({"save_backtest_models": True})
freqai_conf['runmode'] = RunMode.BACKTEST
if is_arm() and model == 'CatboostRegressor': Trade.use_db = False
if is_arm() and "Catboost" in model:
pytest.skip("CatBoost is not supported on ARM") pytest.skip("CatBoost is not supported on ARM")
if is_mac(): if is_mac():
pytest.skip("Reinforcement learning module not available on intel based Mac OS") pytest.skip("Reinforcement learning module not available on intel based Mac OS")
model_save_ext = 'joblib'
freqai_conf.update({"freqaimodel": model}) freqai_conf.update({"freqaimodel": model})
freqai_conf.update({"timerange": "20180110-20180130"}) freqai_conf.update({"timerange": "20180120-20180130"})
freqai_conf.update({"strategy": "freqai_test_strat"}) freqai_conf.update({"strategy": strat})
if 'ReinforcementLearner' in model: if 'ReinforcementLearner' in model:
model_save_ext = 'zip'
freqai_conf.update({"strategy": "freqai_rl_test_strat"})
freqai_conf["freqai"].update({"model_training_parameters": { freqai_conf["freqai"].update({"model_training_parameters": {
"learning_rate": 0.00025, "learning_rate": 0.00025,
"gamma": 0.9, "gamma": 0.9,
@ -218,7 +225,6 @@ def test_start_backtesting(mocker, freqai_conf, model):
if 'test_4ac' in model: if 'test_4ac' in model:
freqai_conf["freqaimodel_path"] = str(Path(__file__).parents[1] / "freqai" / "test_models") freqai_conf["freqaimodel_path"] = str(Path(__file__).parents[1] / "freqai" / "test_models")
strategy = get_patched_freqai_strategy(mocker, freqai_conf) strategy = get_patched_freqai_strategy(mocker, freqai_conf)
exchange = get_patched_exchange(mocker, freqai_conf) exchange = get_patched_exchange(mocker, freqai_conf)
strategy.dp = DataProvider(freqai_conf, exchange) 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) freqai.start_backtesting(df, metadata, freqai.dk)
model_folders = [x for x in freqai.dd.full_path.iterdir() if x.is_dir()] 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)) 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() pairs_b = strategy.gather_informative_pairs()
# we expect unique pairs * timeframes # we expect unique pairs * timeframes
assert len(pairs_b) == len(set(pairlist + corr_pairs)) * len(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,
)