Merge remote-tracking branch 'origin/develop' into add-metric-tracker

This commit is contained in:
robcaulk
2022-10-14 19:00:49 +02:00
72 changed files with 570 additions and 341 deletions

View File

@@ -56,7 +56,7 @@ EXCHANGES = {
'leverage_in_spot_market': True,
},
'kucoin': {
'pair': 'BTC/USDT',
'pair': 'XRP/USDT',
'stake_currency': 'USDT',
'hasQuoteVolume': True,
'timeframe': '5m',

View File

@@ -1834,6 +1834,7 @@ def test_get_tickers(default_conf, mocker, exchange_name):
'last': 41,
}
}
mocker.patch('freqtrade.exchange.exchange.Exchange.exchange_has', return_value=True)
api_mock.fetch_tickers = MagicMock(return_value=tick)
api_mock.fetch_bids_asks = MagicMock(return_value={})
exchange = get_patched_exchange(mocker, default_conf, api_mock, id=exchange_name)
@@ -1883,6 +1884,11 @@ def test_get_tickers(default_conf, mocker, exchange_name):
assert api_mock.fetch_tickers.call_count == 1
assert api_mock.fetch_bids_asks.call_count == (1 if exchange_name == 'binance' else 0)
api_mock.fetch_tickers.reset_mock()
api_mock.fetch_bids_asks.reset_mock()
mocker.patch('freqtrade.exchange.exchange.Exchange.exchange_has', return_value=False)
assert exchange.get_tickers() == {}
@pytest.mark.parametrize("exchange_name", EXCHANGES)
def test_fetch_ticker(default_conf, mocker, exchange_name):

View File

@@ -107,6 +107,8 @@ def make_unfiltered_dataframe(mocker, freqai_conf):
unfiltered_dataframe = freqai.dk.use_strategy_to_populate_indicators(
strategy, corr_dataframes, base_dataframes, freqai.dk.pair
)
for i in range(5):
unfiltered_dataframe[f'constant_{i}'] = i
unfiltered_dataframe = freqai.dk.slice_dataframe(new_timerange, unfiltered_dataframe)

View File

@@ -163,7 +163,7 @@ def test_extract_data_and_train_model_Classifiers(mocker, freqai_conf, model):
("CatboostClassifier", 6, "freqai_test_classifier")
],
)
def test_start_backtesting(mocker, freqai_conf, model, num_files, strat):
def test_start_backtesting(mocker, freqai_conf, model, num_files, strat, caplog):
freqai_conf.get("freqai", {}).update({"save_backtest_models": True})
freqai_conf['runmode'] = RunMode.BACKTEST
Trade.use_db = False
@@ -187,12 +187,23 @@ def test_start_backtesting(mocker, freqai_conf, model, num_files, strat):
corr_df, base_df = freqai.dd.get_base_and_corr_dataframes(sub_timerange, "LTC/BTC", freqai.dk)
df = freqai.dk.use_strategy_to_populate_indicators(strategy, corr_df, base_df, "LTC/BTC")
for i in range(5):
df[f'%-constant_{i}'] = i
# df.loc[:, f'%-constant_{i}'] = i
metadata = {"pair": "LTC/BTC"}
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) == num_files
assert log_has_re(
"Removed features ",
caplog,
)
assert log_has_re(
"Removed 5 features from prediction features, ",
caplog,
)
Backtesting.cleanup()
shutil.rmtree(Path(freqai.dk.full_path))
@@ -262,6 +273,7 @@ def test_start_backtesting_from_existing_folder(mocker, freqai_conf, caplog):
corr_df, base_df = freqai.dd.get_base_and_corr_dataframes(sub_timerange, "LTC/BTC", freqai.dk)
df = freqai.dk.use_strategy_to_populate_indicators(strategy, corr_df, base_df, "LTC/BTC")
freqai.start_backtesting(df, metadata, freqai.dk)
assert log_has_re(
@@ -318,6 +330,7 @@ def test_follow_mode(mocker, freqai_conf):
freqai.dd.load_all_pair_histories(timerange, freqai.dk)
df = strategy.dp.get_pair_dataframe('ADA/BTC', '5m')
freqai.start_live(df, metadata, strategy, freqai.dk)
assert len(freqai.dk.return_dataframe.index) == 5702

View File

@@ -910,8 +910,9 @@ def test_in_strategy_auto_hyperopt_with_parallel(mocker, hyperopt_conf, tmpdir,
})
hyperopt = Hyperopt(hyperopt_conf)
hyperopt.backtesting.exchange.get_max_leverage = lambda *x, **xx: 1.0
hyperopt.backtesting.exchange.get_min_pair_stake_amount = lambda *x, **xx: 1.0
hyperopt.backtesting.exchange.get_min_pair_stake_amount = lambda *x, **xx: 0.00001
hyperopt.backtesting.exchange.get_max_pair_stake_amount = lambda *x, **xx: 100.0
hyperopt.backtesting.exchange._markets = get_markets()
assert isinstance(hyperopt.custom_hyperopt, HyperOptAuto)
assert isinstance(hyperopt.backtesting.strategy.buy_rsi, IntParameter)

View File

@@ -1443,8 +1443,9 @@ def test_api_plot_config(botclient):
assert isinstance(rc.json()['subplots'], dict)
def test_api_strategies(botclient):
def test_api_strategies(botclient, tmpdir):
ftbot, client = botclient
ftbot.config['user_data_dir'] = Path(tmpdir)
rc = client_get(client, f"{BASE_URI}/strategies")

View File

@@ -99,6 +99,7 @@ def test_send_msg_telegram_error(mocker, default_conf, caplog) -> None:
def test_process_msg_queue(mocker, default_conf, caplog) -> None:
telegram_mock = mocker.patch('freqtrade.rpc.telegram.Telegram.send_msg')
default_conf['telegram']['allow_custom_messages'] = True
mocker.patch('freqtrade.rpc.telegram.Telegram._init')
freqtradebot = get_patched_freqtradebot(mocker, default_conf)
@@ -108,8 +109,8 @@ def test_process_msg_queue(mocker, default_conf, caplog) -> None:
queue.append('Test message 2')
rpc_manager.process_msg_queue(queue)
assert log_has("Sending rpc message: {'type': strategy_msg, 'msg': 'Test message'}", caplog)
assert log_has("Sending rpc message: {'type': strategy_msg, 'msg': 'Test message 2'}", caplog)
assert log_has("Sending rpc strategy_msg: Test message", caplog)
assert log_has("Sending rpc strategy_msg: Test message 2", caplog)
assert telegram_mock.call_count == 2

View File

@@ -3,7 +3,6 @@
from datetime import datetime, timedelta
from unittest.mock import MagicMock
import pytest
from requests import RequestException
from freqtrade.enums import ExitType, RPCMessageType
@@ -337,34 +336,18 @@ def test_exception_send_msg(default_conf, mocker, caplog):
caplog)
default_conf["webhook"] = get_webhook_dict()
default_conf["webhook"]["webhookentry"]["value1"] = "{DEADBEEF:8f}"
default_conf["webhook"]["strategy_msg"] = {"value1": "{DEADBEEF:8f}"}
msg_mock = MagicMock()
mocker.patch("freqtrade.rpc.webhook.Webhook._send_msg", msg_mock)
webhook = Webhook(RPC(get_patched_freqtradebot(mocker, default_conf)), default_conf)
msg = {
'type': RPCMessageType.ENTRY,
'exchange': 'Binance',
'pair': 'ETH/BTC',
'limit': 0.005,
'order_type': 'limit',
'stake_amount': 0.8,
'stake_amount_fiat': 500,
'stake_currency': 'BTC',
'fiat_currency': 'EUR'
'type': RPCMessageType.STRATEGY_MSG,
'msg': 'hello world',
}
webhook.send_msg(msg)
assert log_has("Problem calling Webhook. Please check your webhook configuration. "
"Exception: 'DEADBEEF'", caplog)
msg_mock = MagicMock()
mocker.patch("freqtrade.rpc.webhook.Webhook._send_msg", msg_mock)
msg = {
'type': 'DEADBEEF',
'status': 'whatever'
}
with pytest.raises(NotImplementedError):
webhook.send_msg(msg)
# Test no failure for not implemented but known messagetypes
for e in RPCMessageType:
msg = {

View File

@@ -32,7 +32,7 @@ def test_search_strategy():
def test_search_all_strategies_no_failed():
directory = Path(__file__).parent / "strats"
strategies = StrategyResolver.search_all_objects(directory, enum_failed=False)
strategies = StrategyResolver._search_all_objects(directory, enum_failed=False)
assert isinstance(strategies, list)
assert len(strategies) == 9
assert isinstance(strategies[0], dict)
@@ -40,7 +40,7 @@ def test_search_all_strategies_no_failed():
def test_search_all_strategies_with_failed():
directory = Path(__file__).parent / "strats"
strategies = StrategyResolver.search_all_objects(directory, enum_failed=True)
strategies = StrategyResolver._search_all_objects(directory, enum_failed=True)
assert isinstance(strategies, list)
assert len(strategies) == 10
# with enum_failed=True search_all_objects() shall find 2 good strategies
@@ -49,7 +49,7 @@ def test_search_all_strategies_with_failed():
assert len([x for x in strategies if x['class'] is None]) == 1
directory = Path(__file__).parent / "strats_nonexistingdir"
strategies = StrategyResolver.search_all_objects(directory, enum_failed=True)
strategies = StrategyResolver._search_all_objects(directory, enum_failed=True)
assert len(strategies) == 0
@@ -77,10 +77,9 @@ def test_load_strategy_base64(dataframe_1m, caplog, default_conf):
def test_load_strategy_invalid_directory(caplog, default_conf):
default_conf['strategy'] = 'StrategyTestV3'
extra_dir = Path.cwd() / 'some/path'
with pytest.raises(OperationalException):
StrategyResolver._load_strategy(CURRENT_TEST_STRATEGY, config=default_conf,
with pytest.raises(OperationalException, match=r"Impossible to load Strategy.*"):
StrategyResolver._load_strategy('StrategyTestV333', config=default_conf,
extra_dir=extra_dir)
assert log_has_re(r'Path .*' + r'some.*path.*' + r'.* does not exist', caplog)
@@ -102,8 +101,8 @@ def test_load_strategy_noname(default_conf):
StrategyResolver.load_strategy(default_conf)
@pytest.mark.filterwarnings("ignore:deprecated")
@pytest.mark.parametrize('strategy_name', ['StrategyTestV2'])
@ pytest.mark.filterwarnings("ignore:deprecated")
@ pytest.mark.parametrize('strategy_name', ['StrategyTestV2'])
def test_strategy_pre_v3(dataframe_1m, default_conf, strategy_name):
default_conf.update({'strategy': strategy_name})
@@ -349,7 +348,7 @@ def test_strategy_override_use_exit_profit_only(caplog, default_conf):
assert log_has("Override strategy 'exit_profit_only' with value in config file: True.", caplog)
@pytest.mark.filterwarnings("ignore:deprecated")
@ pytest.mark.filterwarnings("ignore:deprecated")
def test_missing_implements(default_conf, caplog):
default_location = Path(__file__).parent / "strats"

View File

@@ -25,7 +25,7 @@ def test_create_userdata_dir(mocker, default_conf, caplog) -> None:
md = mocker.patch.object(Path, 'mkdir', MagicMock())
x = create_userdata_dir('/tmp/bar', create_dir=True)
assert md.call_count == 9
assert md.call_count == 10
assert md.call_args[1]['parents'] is False
assert log_has(f'Created user-data directory: {Path("/tmp/bar")}', caplog)
assert isinstance(x, Path)