Merge branch 'develop' into pr/wizrds/7303

This commit is contained in:
Matthias
2022-09-20 06:56:15 +02:00
103 changed files with 1189 additions and 442 deletions

View File

@@ -2287,7 +2287,7 @@ def tickers():
@pytest.fixture
def result(testdatadir):
def dataframe_1m(testdatadir):
with (testdatadir / 'UNITTEST_BTC-1m.json').open('r') as data_file:
return ohlcv_to_dataframe(json.load(data_file), '1m', pair="UNITTEST/BTC",
fill_missing=True)

View File

@@ -18,8 +18,8 @@ from tests.conftest import log_has, log_has_re
from tests.data.test_history import _clean_test_file
def test_dataframe_correct_columns(result):
assert result.columns.tolist() == ['date', 'open', 'high', 'low', 'close', 'volume']
def test_dataframe_correct_columns(dataframe_1m):
assert dataframe_1m.columns.tolist() == ['date', 'open', 'high', 'low', 'close', 'volume']
def test_ohlcv_to_dataframe(ohlcv_history_list, caplog):

View File

@@ -23,7 +23,7 @@ from tests.exchange.test_exchange import ccxt_exceptionhandlers
def test_stoploss_order_binance(default_conf, mocker, limitratio, expected, side, trademode):
api_mock = MagicMock()
order_id = 'test_prod_buy_{}'.format(randint(0, 10 ** 6))
order_type = 'stop_loss_limit' if trademode == TradingMode.SPOT else 'stop'
order_type = 'stop_loss_limit' if trademode == TradingMode.SPOT else 'limit'
api_mock.create_order = MagicMock(return_value={
'id': order_id,
@@ -45,12 +45,15 @@ def test_stoploss_order_binance(default_conf, mocker, limitratio, expected, side
amount=1,
stop_price=190,
side=side,
order_types={'stoploss_on_exchange_limit_ratio': 1.05},
order_types={'stoploss': 'limit', 'stoploss_on_exchange_limit_ratio': 1.05},
leverage=1.0
)
api_mock.create_order.reset_mock()
order_types = {} if limitratio is None else {'stoploss_on_exchange_limit_ratio': limitratio}
order_types = {'stoploss': 'limit'}
if limitratio is not None:
order_types.update({'stoploss_on_exchange_limit_ratio': limitratio})
order = exchange.stoploss(
pair='ETH/BTC',
amount=1,

View File

@@ -472,7 +472,7 @@ def test_load_leverage_tiers_okx(default_conf, mocker, markets, tmpdir, caplog,
api_mock.fetch_market_leverage_tiers.call_count == 0
# 2 day passes ...
time_machine.move_to(datetime.now() + timedelta(days=2))
time_machine.move_to(datetime.now() + timedelta(weeks=5))
exchange.load_leverage_tiers()
assert log_has(logmsg, caplog)

View File

@@ -8,6 +8,7 @@ import pytest
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
@@ -315,3 +316,62 @@ def test_principal_component_analysis(mocker, freqai_conf):
assert Path(freqai.dk.data_path / f"{freqai.dk.model_filename}_pca_object.pkl")
shutil.rmtree(Path(freqai.dk.full_path))
def test_plot_feature_importance(mocker, freqai_conf):
from freqtrade.freqai.utils import plot_feature_importance
freqai_conf.update({"timerange": "20180110-20180130"})
freqai_conf.get("freqai", {}).get("feature_parameters", {}).update(
{"princpial_component_analysis": "true"})
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.live = True
freqai.dk = FreqaiDataKitchen(freqai_conf)
timerange = TimeRange.parse_timerange("20180110-20180130")
freqai.dd.load_all_pair_histories(timerange, freqai.dk)
freqai.dd.pair_dict = MagicMock()
data_load_timerange = TimeRange.parse_timerange("20180110-20180130")
new_timerange = TimeRange.parse_timerange("20180120-20180130")
freqai.extract_data_and_train_model(
new_timerange, "ADA/BTC", strategy, freqai.dk, data_load_timerange)
model = freqai.dd.load_data("ADA/BTC", freqai.dk)
plot_feature_importance(model, "ADA/BTC", freqai.dk)
assert Path(freqai.dk.data_path / f"{freqai.dk.model_filename}.html")
shutil.rmtree(Path(freqai.dk.full_path))
@pytest.mark.parametrize('timeframes,corr_pairs', [
(['5m'], ['ADA/BTC', 'DASH/BTC']),
(['5m'], ['ADA/BTC', 'DASH/BTC', 'ETH/USDT']),
(['5m', '15m'], ['ADA/BTC', 'DASH/BTC', 'ETH/USDT']),
])
def test_freqai_informative_pairs(mocker, freqai_conf, timeframes, corr_pairs):
freqai_conf['freqai']['feature_parameters'].update({
'include_timeframes': timeframes,
'include_corr_pairlist': corr_pairs,
})
strategy = get_patched_freqai_strategy(mocker, freqai_conf)
exchange = get_patched_exchange(mocker, freqai_conf)
pairlists = PairListManager(exchange, freqai_conf)
strategy.dp = DataProvider(freqai_conf, exchange, pairlists)
pairlist = strategy.dp.current_whitelist()
pairs_a = strategy.informative_pairs()
assert len(pairs_a) == 0
pairs_b = strategy.gather_informative_pairs()
# we expect unique pairs * timeframes
assert len(pairs_b) == len(set(pairlist + corr_pairs)) * len(timeframes)

View File

@@ -43,19 +43,6 @@ class freqai_test_multimodel_strat(IStrategy):
)
max_roi_time_long = IntParameter(0, 800, default=400, space="sell", optimize=False, load=True)
def informative_pairs(self):
whitelist_pairs = self.dp.current_whitelist()
corr_pairs = self.config["freqai"]["feature_parameters"]["include_corr_pairlist"]
informative_pairs = []
for tf in self.config["freqai"]["feature_parameters"]["include_timeframes"]:
for pair in whitelist_pairs:
informative_pairs.append((pair, tf))
for pair in corr_pairs:
if pair in whitelist_pairs:
continue # avoid duplication
informative_pairs.append((pair, tf))
return informative_pairs
def populate_any_indicators(
self, pair, df, tf, informative=None, set_generalized_indicators=False
):

View File

@@ -43,19 +43,6 @@ class freqai_test_strat(IStrategy):
)
max_roi_time_long = IntParameter(0, 800, default=400, space="sell", optimize=False, load=True)
def informative_pairs(self):
whitelist_pairs = self.dp.current_whitelist()
corr_pairs = self.config["freqai"]["feature_parameters"]["include_corr_pairlist"]
informative_pairs = []
for tf in self.config["freqai"]["feature_parameters"]["include_timeframes"]:
for pair in whitelist_pairs:
informative_pairs.append((pair, tf))
for pair in corr_pairs:
if pair in whitelist_pairs:
continue # avoid duplication
informative_pairs.append((pair, tf))
return informative_pairs
def populate_any_indicators(
self, pair, df, tf, informative=None, set_generalized_indicators=False
):

View File

@@ -21,14 +21,14 @@ def test_strategy_test_v3_structure():
(True, 'short'),
(False, 'long'),
])
def test_strategy_test_v3(result, fee, is_short, side):
def test_strategy_test_v3(dataframe_1m, fee, is_short, side):
strategy = StrategyTestV3({})
metadata = {'pair': 'ETH/BTC'}
assert type(strategy.minimal_roi) is dict
assert type(strategy.stoploss) is float
assert type(strategy.timeframe) is str
indicators = strategy.populate_indicators(result, metadata)
indicators = strategy.populate_indicators(dataframe_1m, metadata)
assert type(indicators) is DataFrame
assert type(strategy.populate_buy_trend(indicators, metadata)) is DataFrame
assert type(strategy.populate_sell_trend(indicators, metadata)) is DataFrame

View File

@@ -53,7 +53,7 @@ def test_search_all_strategies_with_failed():
assert len(strategies) == 0
def test_load_strategy(default_conf, result):
def test_load_strategy(default_conf, dataframe_1m):
default_conf.update({'strategy': 'SampleStrategy',
'strategy_path': str(Path(__file__).parents[2] / 'freqtrade/templates')
})
@@ -61,22 +61,22 @@ def test_load_strategy(default_conf, result):
assert isinstance(strategy.__source__, str)
assert 'class SampleStrategy' in strategy.__source__
assert isinstance(strategy.__file__, str)
assert 'rsi' in strategy.advise_indicators(result, {'pair': 'ETH/BTC'})
assert 'rsi' in strategy.advise_indicators(dataframe_1m, {'pair': 'ETH/BTC'})
def test_load_strategy_base64(result, caplog, default_conf):
def test_load_strategy_base64(dataframe_1m, caplog, default_conf):
filepath = Path(__file__).parents[2] / 'freqtrade/templates/sample_strategy.py'
encoded_string = urlsafe_b64encode(filepath.read_bytes()).decode("utf-8")
default_conf.update({'strategy': 'SampleStrategy:{}'.format(encoded_string)})
strategy = StrategyResolver.load_strategy(default_conf)
assert 'rsi' in strategy.advise_indicators(result, {'pair': 'ETH/BTC'})
assert 'rsi' in strategy.advise_indicators(dataframe_1m, {'pair': 'ETH/BTC'})
# Make sure strategy was loaded from base64 (using temp directory)!!
assert log_has_re(r"Using resolved strategy SampleStrategy from '"
r".*(/|\\).*(/|\\)SampleStrategy\.py'\.\.\.", caplog)
def test_load_strategy_invalid_directory(result, 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):
@@ -104,7 +104,7 @@ def test_load_strategy_noname(default_conf):
@pytest.mark.filterwarnings("ignore:deprecated")
@pytest.mark.parametrize('strategy_name', ['StrategyTestV2'])
def test_strategy_pre_v3(result, default_conf, strategy_name):
def test_strategy_pre_v3(dataframe_1m, default_conf, strategy_name):
default_conf.update({'strategy': strategy_name})
strategy = StrategyResolver.load_strategy(default_conf)
@@ -118,7 +118,7 @@ def test_strategy_pre_v3(result, default_conf, strategy_name):
assert strategy.timeframe == '5m'
assert default_conf['timeframe'] == '5m'
df_indicators = strategy.advise_indicators(result, metadata=metadata)
df_indicators = strategy.advise_indicators(dataframe_1m, metadata=metadata)
assert 'adx' in df_indicators
dataframe = strategy.advise_entry(df_indicators, metadata=metadata)
@@ -417,24 +417,24 @@ def test_call_deprecated_function(default_conf):
StrategyResolver.load_strategy(default_conf)
def test_strategy_interface_versioning(result, default_conf):
def test_strategy_interface_versioning(dataframe_1m, default_conf):
default_conf.update({'strategy': 'StrategyTestV2'})
strategy = StrategyResolver.load_strategy(default_conf)
metadata = {'pair': 'ETH/BTC'}
assert strategy.INTERFACE_VERSION == 2
indicator_df = strategy.advise_indicators(result, metadata=metadata)
indicator_df = strategy.advise_indicators(dataframe_1m, metadata=metadata)
assert isinstance(indicator_df, DataFrame)
assert 'adx' in indicator_df.columns
enterdf = strategy.advise_entry(result, metadata=metadata)
enterdf = strategy.advise_entry(dataframe_1m, metadata=metadata)
assert isinstance(enterdf, DataFrame)
assert 'buy' not in enterdf.columns
assert 'enter_long' in enterdf.columns
exitdf = strategy.advise_exit(result, metadata=metadata)
exitdf = strategy.advise_exit(dataframe_1m, metadata=metadata)
assert isinstance(exitdf, DataFrame)
assert 'sell' not in exitdf
assert 'exit_long' in exitdf

View File

@@ -1427,6 +1427,7 @@ def test_handle_stoploss_on_exchange_trailing(
trade.is_open = True
trade.open_order_id = None
trade.stoploss_order_id = 100
trade.stoploss_last_update = arrow.utcnow().shift(minutes=-20).datetime
stoploss_order_hanging = MagicMock(return_value={
'id': 100,
@@ -1456,7 +1457,7 @@ def test_handle_stoploss_on_exchange_trailing(
)
cancel_order_mock = MagicMock()
stoploss_order_mock = MagicMock(return_value={'id': 13434334})
stoploss_order_mock = MagicMock(return_value={'id': 'so1'})
mocker.patch('freqtrade.exchange.Binance.cancel_stoploss_order', cancel_order_mock)
mocker.patch('freqtrade.exchange.Binance.stoploss', stoploss_order_mock)
@@ -1569,6 +1570,7 @@ def test_handle_stoploss_on_exchange_trailing_error(
assert stoploss.call_count == 1
# Fail creating stoploss order
trade.stoploss_last_update = arrow.utcnow().shift(minutes=-601).datetime
caplog.clear()
cancel_mock = mocker.patch("freqtrade.exchange.Binance.cancel_stoploss_order", MagicMock())
mocker.patch("freqtrade.exchange.Binance.stoploss", side_effect=ExchangeError())
@@ -1657,6 +1659,7 @@ def test_handle_stoploss_on_exchange_custom_stop(
trade.is_open = True
trade.open_order_id = None
trade.stoploss_order_id = 100
trade.stoploss_last_update = arrow.utcnow().shift(minutes=-601).datetime
stoploss_order_hanging = MagicMock(return_value={
'id': 100,
@@ -1685,7 +1688,7 @@ def test_handle_stoploss_on_exchange_custom_stop(
)
cancel_order_mock = MagicMock()
stoploss_order_mock = MagicMock(return_value={'id': 13434334})
stoploss_order_mock = MagicMock(return_value={'id': 'so1'})
mocker.patch('freqtrade.exchange.Binance.cancel_stoploss_order', cancel_order_mock)
mocker.patch('freqtrade.exchange.Binance.stoploss', stoploss_order_mock)
@@ -1727,8 +1730,7 @@ def test_handle_stoploss_on_exchange_custom_stop(
assert freqtrade.handle_trade(trade) is True
def test_tsl_on_exchange_compatible_with_edge(mocker, edge_conf, fee, caplog,
limit_order) -> None:
def test_tsl_on_exchange_compatible_with_edge(mocker, edge_conf, fee, limit_order) -> None:
enter_order = limit_order['buy']
exit_order = limit_order['sell']
@@ -1784,6 +1786,7 @@ def test_tsl_on_exchange_compatible_with_edge(mocker, edge_conf, fee, caplog,
trade.is_open = True
trade.open_order_id = None
trade.stoploss_order_id = 100
trade.stoploss_last_update = arrow.utcnow()
stoploss_order_hanging = MagicMock(return_value={
'id': 100,

View File

@@ -185,8 +185,8 @@ def test_render_template_fallback(mocker):
templatefile='subtemplates/indicators_does-not-exist.j2',)
val = render_template_with_fallback(
templatefile='subtemplates/indicators_does-not-exist.j2',
templatefallbackfile='subtemplates/indicators_minimal.j2',
templatefile='strategy_subtemplates/indicators_does-not-exist.j2',
templatefallbackfile='strategy_subtemplates/indicators_minimal.j2',
)
assert isinstance(val, str)
assert 'if self.dp' in val