Merge pull request #5936 from rokups/rk/decorator-fix
Use market data to get base and quote currencies in @informative() decorator
This commit is contained in:
		| @@ -67,7 +67,7 @@ class Backtesting: | ||||
|         self.all_results: Dict[str, Dict] = {} | ||||
|  | ||||
|         self.exchange = ExchangeResolver.load_exchange(self.config['exchange']['name'], self.config) | ||||
|         self.dataprovider = DataProvider(self.config, None) | ||||
|         self.dataprovider = DataProvider(self.config, self.exchange) | ||||
|  | ||||
|         if self.config.get('strategy_list', None): | ||||
|             for strat in list(self.config['strategy_list']): | ||||
|   | ||||
| @@ -80,12 +80,11 @@ def _create_and_merge_informative_pair(strategy, dataframe: DataFrame, metadata: | ||||
|         # Not specifying an asset will define informative dataframe for current pair. | ||||
|         asset = metadata['pair'] | ||||
|  | ||||
|     if '/' in asset: | ||||
|         base, quote = asset.split('/') | ||||
|     else: | ||||
|         # When futures are supported this may need reevaluation. | ||||
|         # base, quote = asset, '' | ||||
|         raise OperationalException('Not implemented.') | ||||
|     market = strategy.dp.market(asset) | ||||
|     if market is None: | ||||
|         raise OperationalException(f'Market {asset} is not available.') | ||||
|     base = market['base'] | ||||
|     quote = market['quote'] | ||||
|  | ||||
|     # Default format. This optimizes for the common case: informative pairs using same stake | ||||
|     # currency. When quote currency matches stake currency, column name will omit base currency. | ||||
|   | ||||
| @@ -20,7 +20,7 @@ class InformativeDecoratorTest(IStrategy): | ||||
|     startup_candle_count: int = 20 | ||||
|  | ||||
|     def informative_pairs(self): | ||||
|         return [('BTC/USDT', '5m')] | ||||
|         return [('NEO/USDT', '5m')] | ||||
|  | ||||
|     def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: | ||||
|         dataframe['buy'] = 0 | ||||
| @@ -38,8 +38,8 @@ class InformativeDecoratorTest(IStrategy): | ||||
|         return dataframe | ||||
|  | ||||
|     # Simple informative test. | ||||
|     @informative('1h', 'BTC/{stake}') | ||||
|     def populate_indicators_btc_1h(self, dataframe: DataFrame, metadata: dict) -> DataFrame: | ||||
|     @informative('1h', 'NEO/{stake}') | ||||
|     def populate_indicators_neo_1h(self, dataframe: DataFrame, metadata: dict) -> DataFrame: | ||||
|         dataframe['rsi'] = 14 | ||||
|         return dataframe | ||||
|  | ||||
| @@ -50,7 +50,7 @@ class InformativeDecoratorTest(IStrategy): | ||||
|         return dataframe | ||||
|  | ||||
|     # Formatting test. | ||||
|     @informative('30m', 'BTC/{stake}', '{column}_{BASE}_{QUOTE}_{base}_{quote}_{asset}_{timeframe}') | ||||
|     @informative('30m', 'NEO/{stake}', '{column}_{BASE}_{QUOTE}_{base}_{quote}_{asset}_{timeframe}') | ||||
|     def populate_indicators_btc_1h_2(self, dataframe: DataFrame, metadata: dict) -> DataFrame: | ||||
|         dataframe['rsi'] = 14 | ||||
|         return dataframe | ||||
| @@ -68,7 +68,7 @@ class InformativeDecoratorTest(IStrategy): | ||||
|         dataframe['rsi_less'] = dataframe['rsi'] < dataframe['rsi_1h'] | ||||
|  | ||||
|         # Mixing manual informative pairs with decorators. | ||||
|         informative = self.dp.get_pair_dataframe('BTC/USDT', '5m') | ||||
|         informative = self.dp.get_pair_dataframe('NEO/USDT', '5m') | ||||
|         informative['rsi'] = 14 | ||||
|         dataframe = merge_informative_pair(dataframe, informative, self.timeframe, '5m', ffill=True) | ||||
|  | ||||
|   | ||||
| @@ -7,6 +7,7 @@ import pytest | ||||
| from freqtrade.data.dataprovider import DataProvider | ||||
| from freqtrade.strategy import (merge_informative_pair, stoploss_from_absolute, stoploss_from_open, | ||||
|                                 timeframe_to_minutes) | ||||
| from tests.conftest import get_patched_exchange | ||||
|  | ||||
|  | ||||
| def generate_test_data(timeframe: str, size: int, start: str = '2020-07-05'): | ||||
| @@ -155,9 +156,9 @@ def test_informative_decorator(mocker, default_conf): | ||||
|         ('LTC/USDT', '5m'): test_data_5m, | ||||
|         ('LTC/USDT', '30m'): test_data_30m, | ||||
|         ('LTC/USDT', '1h'): test_data_1h, | ||||
|         ('BTC/USDT', '30m'): test_data_30m, | ||||
|         ('BTC/USDT', '5m'): test_data_5m, | ||||
|         ('BTC/USDT', '1h'): test_data_1h, | ||||
|         ('NEO/USDT', '30m'): test_data_30m, | ||||
|         ('NEO/USDT', '5m'): test_data_5m, | ||||
|         ('NEO/USDT', '1h'): test_data_1h, | ||||
|         ('ETH/USDT', '1h'): test_data_1h, | ||||
|         ('ETH/USDT', '30m'): test_data_30m, | ||||
|         ('ETH/BTC', '1h'): test_data_1h, | ||||
| @@ -165,15 +166,16 @@ def test_informative_decorator(mocker, default_conf): | ||||
|     from .strats.informative_decorator_strategy import InformativeDecoratorTest | ||||
|     default_conf['stake_currency'] = 'USDT' | ||||
|     strategy = InformativeDecoratorTest(config=default_conf) | ||||
|     strategy.dp = DataProvider({}, None, None) | ||||
|     exchange = get_patched_exchange(mocker, default_conf) | ||||
|     strategy.dp = DataProvider({}, exchange, None) | ||||
|     mocker.patch.object(strategy.dp, 'current_whitelist', return_value=[ | ||||
|         'XRP/USDT', 'LTC/USDT', 'BTC/USDT' | ||||
|         'XRP/USDT', 'LTC/USDT', 'NEO/USDT' | ||||
|     ]) | ||||
|  | ||||
|     assert len(strategy._ft_informative) == 6   # Equal to number of decorators used | ||||
|     informative_pairs = [('XRP/USDT', '1h'), ('LTC/USDT', '1h'), ('XRP/USDT', '30m'), | ||||
|                          ('LTC/USDT', '30m'), ('BTC/USDT', '1h'), ('BTC/USDT', '30m'), | ||||
|                          ('BTC/USDT', '5m'), ('ETH/BTC', '1h'), ('ETH/USDT', '30m')] | ||||
|                          ('LTC/USDT', '30m'), ('NEO/USDT', '1h'), ('NEO/USDT', '30m'), | ||||
|                          ('NEO/USDT', '5m'), ('ETH/BTC', '1h'), ('ETH/USDT', '30m')] | ||||
|     for inf_pair in informative_pairs: | ||||
|         assert inf_pair in strategy.gather_informative_pairs() | ||||
|  | ||||
| @@ -186,8 +188,8 @@ def test_informative_decorator(mocker, default_conf): | ||||
|         {p: data[(p, strategy.timeframe)] for p in ('XRP/USDT', 'LTC/USDT')}) | ||||
|     expected_columns = [ | ||||
|         'rsi_1h', 'rsi_30m',                    # Stacked informative decorators | ||||
|         'btc_usdt_rsi_1h',                      # BTC 1h informative | ||||
|         'rsi_BTC_USDT_btc_usdt_BTC/USDT_30m',   # Column formatting | ||||
|         'neo_usdt_rsi_1h',                      # NEO 1h informative | ||||
|         'rsi_NEO_USDT_neo_usdt_NEO/USDT_30m',   # Column formatting | ||||
|         'rsi_from_callable',                    # Custom column formatter | ||||
|         'eth_btc_rsi_1h',                       # Quote currency not matching stake currency | ||||
|         'rsi', 'rsi_less',                      # Non-informative columns | ||||
|   | ||||
		Reference in New Issue
	
	Block a user