Merge pull request #6312 from freqtrade/short_informative_decorator

Short informative decorator
This commit is contained in:
Matthias
2022-01-30 15:33:52 +01:00
committed by GitHub
5 changed files with 69 additions and 45 deletions

View File

@@ -20,7 +20,11 @@ class InformativeDecoratorTest(IStrategy):
def informative_pairs(self):
# Intentionally return 2 tuples, must be converted to 3 in compatibility code
return [('NEO/USDT', '5m')]
return [
('NEO/USDT', '5m'),
('NEO/USDT', '15m', ''),
('NEO/USDT', '2h', 'futures'),
]
def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
dataframe['buy'] = 0
@@ -44,7 +48,7 @@ class InformativeDecoratorTest(IStrategy):
return dataframe
# Quote currency different from stake currency test.
@informative('1h', 'ETH/BTC')
@informative('1h', 'ETH/BTC', candle_type='spot')
def populate_indicators_eth_btc_1h(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
dataframe['rsi'] = 14
return dataframe

View File

@@ -6,6 +6,7 @@ import pytest
from freqtrade.data.dataprovider import DataProvider
from freqtrade.enums import CandleType
from freqtrade.resolvers.strategy_resolver import StrategyResolver
from freqtrade.strategy import (merge_informative_pair, stoploss_from_absolute, stoploss_from_open,
timeframe_to_minutes)
from tests.conftest import get_patched_exchange
@@ -171,29 +172,31 @@ def test_stoploss_from_absolute():
assert pytest.approx(stoploss_from_absolute(100, 1, True)) == 1
# TODO-lev: @pytest.mark.parametrize('candle_type', ['mark', ''])
def test_informative_decorator(mocker, default_conf):
@pytest.mark.parametrize('trading_mode', ['futures', 'spot'])
def test_informative_decorator(mocker, default_conf_usdt, trading_mode):
candle_def = CandleType.get_default(trading_mode)
default_conf_usdt['candle_type_def'] = candle_def
test_data_5m = generate_test_data('5m', 40)
test_data_30m = generate_test_data('30m', 40)
test_data_1h = generate_test_data('1h', 40)
data = {
('XRP/USDT', '5m', CandleType.SPOT): test_data_5m,
('XRP/USDT', '30m', CandleType.SPOT): test_data_30m,
('XRP/USDT', '1h', CandleType.SPOT): test_data_1h,
('LTC/USDT', '5m', CandleType.SPOT): test_data_5m,
('LTC/USDT', '30m', CandleType.SPOT): test_data_30m,
('LTC/USDT', '1h', CandleType.SPOT): test_data_1h,
('NEO/USDT', '30m', CandleType.SPOT): test_data_30m,
('NEO/USDT', '5m', CandleType.SPOT): test_data_5m,
('NEO/USDT', '1h', CandleType.SPOT): test_data_1h,
('ETH/USDT', '1h', CandleType.SPOT): test_data_1h,
('ETH/USDT', '30m', CandleType.SPOT): test_data_30m,
('ETH/BTC', '1h', CandleType.SPOT): test_data_1h,
('XRP/USDT', '5m', candle_def): test_data_5m,
('XRP/USDT', '30m', candle_def): test_data_30m,
('XRP/USDT', '1h', candle_def): test_data_1h,
('LTC/USDT', '5m', candle_def): test_data_5m,
('LTC/USDT', '30m', candle_def): test_data_30m,
('LTC/USDT', '1h', candle_def): test_data_1h,
('NEO/USDT', '30m', candle_def): test_data_30m,
('NEO/USDT', '5m', CandleType.SPOT): test_data_5m, # Explicit request with '' as candletype
('NEO/USDT', '15m', candle_def): test_data_5m, # Explicit request with '' as candletype
('NEO/USDT', '1h', candle_def): test_data_1h,
('ETH/USDT', '1h', candle_def): test_data_1h,
('ETH/USDT', '30m', candle_def): test_data_30m,
('ETH/BTC', '1h', CandleType.SPOT): test_data_1h, # Explicitly selected as spot
}
from .strats.informative_decorator_strategy import InformativeDecoratorTest
default_conf['stake_currency'] = 'USDT'
strategy = InformativeDecoratorTest(config=default_conf)
exchange = get_patched_exchange(mocker, default_conf)
default_conf_usdt['strategy'] = 'InformativeDecoratorTest'
strategy = StrategyResolver.load_strategy(default_conf_usdt)
exchange = get_patched_exchange(mocker, default_conf_usdt)
strategy.dp = DataProvider({}, exchange, None)
mocker.patch.object(strategy.dp, 'current_whitelist', return_value=[
'XRP/USDT', 'LTC/USDT', 'NEO/USDT'
@@ -201,26 +204,29 @@ def test_informative_decorator(mocker, default_conf):
assert len(strategy._ft_informative) == 6 # Equal to number of decorators used
informative_pairs = [
('XRP/USDT', '1h', CandleType.SPOT),
('LTC/USDT', '1h', CandleType.SPOT),
('XRP/USDT', '30m', CandleType.SPOT),
('LTC/USDT', '30m', CandleType.SPOT),
('NEO/USDT', '1h', CandleType.SPOT),
('NEO/USDT', '30m', CandleType.SPOT),
('NEO/USDT', '5m', CandleType.SPOT),
('ETH/BTC', '1h', CandleType.SPOT),
('ETH/USDT', '30m', CandleType.SPOT)]
('XRP/USDT', '1h', candle_def),
('LTC/USDT', '1h', candle_def),
('XRP/USDT', '30m', candle_def),
('LTC/USDT', '30m', candle_def),
('NEO/USDT', '1h', candle_def),
('NEO/USDT', '30m', candle_def),
('NEO/USDT', '5m', candle_def),
('NEO/USDT', '15m', candle_def),
('NEO/USDT', '2h', CandleType.FUTURES),
('ETH/BTC', '1h', CandleType.SPOT), # One candle remains as spot
('ETH/USDT', '30m', candle_def)]
for inf_pair in informative_pairs:
assert inf_pair in strategy.gather_informative_pairs()
def test_historic_ohlcv(pair, timeframe, candle_type):
return data[
(pair, timeframe or strategy.timeframe, CandleType.from_string(candle_type))].copy()
mocker.patch('freqtrade.data.dataprovider.DataProvider.historic_ohlcv',
side_effect=test_historic_ohlcv)
analyzed = strategy.advise_all_indicators(
{p: data[(p, strategy.timeframe, CandleType.SPOT)] for p in ('XRP/USDT', 'LTC/USDT')})
{p: data[(p, strategy.timeframe, candle_def)] for p in ('XRP/USDT', 'LTC/USDT')})
expected_columns = [
'rsi_1h', 'rsi_30m', # Stacked informative decorators
'neo_usdt_rsi_1h', # NEO 1h informative