[SQUASH] Unconditionally include quote currency when asset is explicitly specified. Added docs suggesting to use string formatting to make strategy independent of configured stake currency.
This commit is contained in:
		| @@ -698,10 +698,7 @@ def informative(timeframe: str, asset: str = '', | |||||||
|     current pair. |     current pair. | ||||||
|     :param fmt: Column format (str) or column formatter (callable(name, asset, timeframe)). When not |     :param fmt: Column format (str) or column formatter (callable(name, asset, timeframe)). When not | ||||||
|     specified, defaults to: |     specified, defaults to: | ||||||
|     * {base}_{column}_{timeframe} if asset is specified and quote currency does match stake |     * {base}_{quote}_{column}_{timeframe} if asset is specified.  | ||||||
|     currency.  |  | ||||||
|     * {base}_{quote}_{column}_{timeframe} if asset is specified and quote currency does not match  |  | ||||||
|     stake currency.  |  | ||||||
|     * {column}_{timeframe} if asset is not specified. |     * {column}_{timeframe} if asset is not specified. | ||||||
|     Format string supports these format variables: |     Format string supports these format variables: | ||||||
|     * {asset} - full name of the asset, for example 'BTC/USDT'. |     * {asset} - full name of the asset, for example 'BTC/USDT'. | ||||||
| @@ -746,7 +743,7 @@ for more information. | |||||||
|         # Define BTC/STAKE informative pair. Available in populate_indicators and other methods as |         # Define BTC/STAKE informative pair. Available in populate_indicators and other methods as | ||||||
|         # 'btc_rsi_1h'. Current stake currency should be specified as {stake} format variable  |         # 'btc_rsi_1h'. Current stake currency should be specified as {stake} format variable  | ||||||
|         # instead of hardcoding actual stake currency. Available in populate_indicators and other  |         # instead of hardcoding actual stake currency. Available in populate_indicators and other  | ||||||
|         # methods as 'btc_rsi_1h'. |         # methods as 'btc_usdt_rsi_1h' (when stake currency is USDT). | ||||||
|         @informative('1h', 'BTC/{stake}') |         @informative('1h', 'BTC/{stake}') | ||||||
|         def populate_indicators_btc_1h(self, dataframe: DataFrame, metadata: dict) -> DataFrame: |         def populate_indicators_btc_1h(self, dataframe: DataFrame, metadata: dict) -> DataFrame: | ||||||
|             dataframe['rsi'] = ta.RSI(dataframe, timeperiod=14) |             dataframe['rsi'] = ta.RSI(dataframe, timeperiod=14) | ||||||
| @@ -780,6 +777,25 @@ for more information. | |||||||
|     Do not use `@informative` decorator if you need to use data of one informative pair when generating another informative pair. Instead, define informative pairs |     Do not use `@informative` decorator if you need to use data of one informative pair when generating another informative pair. Instead, define informative pairs | ||||||
|     manually as described [in the DataProvider section](#complete-data-provider-sample). |     manually as described [in the DataProvider section](#complete-data-provider-sample). | ||||||
|  |  | ||||||
|  | !!! Note | ||||||
|  |     Use string formatting when accessing informative dataframes of other pairs. This will allow easily changing stake currency in config without having to adjust strategy code. | ||||||
|  |  | ||||||
|  |     ``` python | ||||||
|  |     def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: | ||||||
|  |         stake = self.config['stake_currency'] | ||||||
|  |         dataframe.loc[ | ||||||
|  |             ( | ||||||
|  |                 (dataframe[f'btc_{stake}_rsi_1h'] < 35) | ||||||
|  |                 & | ||||||
|  |                 (dataframe['volume'] > 0) | ||||||
|  |             ), | ||||||
|  |             ['buy', 'buy_tag']] = (1, 'buy_signal_rsi') | ||||||
|  |      | ||||||
|  |         return dataframe | ||||||
|  |     ``` | ||||||
|  |  | ||||||
|  |     Alternatively column renaming may be used to remove stake currency from column names: `@informative('1h', 'BTC/{stake}', fmt='{base}_{column}_{timeframe}')`. | ||||||
|  |  | ||||||
| !!! Warning "Duplicate method names" | !!! Warning "Duplicate method names" | ||||||
|     Methods tagged with `@informative()` decorator must always have unique names! Re-using same name (for example when copy-pasting already defined informative method) |     Methods tagged with `@informative()` decorator must always have unique names! Re-using same name (for example when copy-pasting already defined informative method) | ||||||
|     will overwrite previously defined method and not produce any errors due to limitations of Python programming language. In such cases you will find that indicators |     will overwrite previously defined method and not produce any errors due to limitations of Python programming language. In such cases you will find that indicators | ||||||
|   | |||||||
| @@ -36,10 +36,7 @@ def informative(timeframe: str, asset: str = '', | |||||||
|     current pair. |     current pair. | ||||||
|     :param fmt: Column format (str) or column formatter (callable(name, asset, timeframe)). When not |     :param fmt: Column format (str) or column formatter (callable(name, asset, timeframe)). When not | ||||||
|     specified, defaults to: |     specified, defaults to: | ||||||
|     * {base}_{column}_{timeframe} if asset is specified and quote currency does match stake |     * {base}_{quote}_{column}_{timeframe} if asset is specified. | ||||||
|     currency. |  | ||||||
|     * {base}_{quote}_{column}_{timeframe} if asset is specified and quote currency does not match |  | ||||||
|     stake currency. |  | ||||||
|     * {column}_{timeframe} if asset is not specified. |     * {column}_{timeframe} if asset is not specified. | ||||||
|     Format string supports these format variables: |     Format string supports these format variables: | ||||||
|     * {asset} - full name of the asset, for example 'BTC/USDT'. |     * {asset} - full name of the asset, for example 'BTC/USDT'. | ||||||
| @@ -88,7 +85,7 @@ def _create_and_merge_informative_pair(strategy, dataframe: DataFrame, metadata: | |||||||
|         base, quote = asset.split('/') |         base, quote = asset.split('/') | ||||||
|     else: |     else: | ||||||
|         # When futures are supported this may need reevaluation. |         # When futures are supported this may need reevaluation. | ||||||
|         # base, quote = asset, None |         # base, quote = asset, '' | ||||||
|         raise OperationalException('Not implemented.') |         raise OperationalException('Not implemented.') | ||||||
|  |  | ||||||
|     # Default format. This optimizes for the common case: informative pairs using same stake |     # Default format. This optimizes for the common case: informative pairs using same stake | ||||||
| @@ -98,10 +95,8 @@ def _create_and_merge_informative_pair(strategy, dataframe: DataFrame, metadata: | |||||||
|     # fmt='{base}_{quote}_{column}_{timeframe}' format or similar. |     # fmt='{base}_{quote}_{column}_{timeframe}' format or similar. | ||||||
|     if not fmt: |     if not fmt: | ||||||
|         fmt = '{column}_{timeframe}'                # Informatives of current pair |         fmt = '{column}_{timeframe}'                # Informatives of current pair | ||||||
|         if quote != config['stake_currency']: |  | ||||||
|             fmt = '{quote}_' + fmt                  # Informatives of different quote currency |  | ||||||
|         if inf_data.asset: |         if inf_data.asset: | ||||||
|             fmt = '{base}_' + fmt                   # Informatives of other pair |             fmt = '{base}_{quote}_' + fmt           # Informatives of other pairs | ||||||
|  |  | ||||||
|     inf_metadata = {'pair': asset, 'timeframe': timeframe} |     inf_metadata = {'pair': asset, 'timeframe': timeframe} | ||||||
|     inf_dataframe = strategy.dp.get_pair_dataframe(asset, timeframe) |     inf_dataframe = strategy.dp.get_pair_dataframe(asset, timeframe) | ||||||
|   | |||||||
| @@ -177,7 +177,7 @@ def test_informative_decorator(mocker, default_conf): | |||||||
|         {p: data[(p, strategy.timeframe)] for p in ('XRP/USDT', 'LTC/USDT')}) |         {p: data[(p, strategy.timeframe)] for p in ('XRP/USDT', 'LTC/USDT')}) | ||||||
|     expected_columns = [ |     expected_columns = [ | ||||||
|         'rsi_1h', 'rsi_30m',                    # Stacked informative decorators |         'rsi_1h', 'rsi_30m',                    # Stacked informative decorators | ||||||
|         'btc_rsi_1h',                           # BTC 1h informative |         'btc_usdt_rsi_1h',                      # BTC 1h informative | ||||||
|         'rsi_BTC_USDT_btc_usdt_BTC/USDT_30m',   # Column formatting |         'rsi_BTC_USDT_btc_usdt_BTC/USDT_30m',   # Column formatting | ||||||
|         'rsi_from_callable',                    # Custom column formatter |         'rsi_from_callable',                    # Custom column formatter | ||||||
|         'eth_btc_rsi_1h',                       # Quote currency not matching stake currency |         'eth_btc_rsi_1h',                       # Quote currency not matching stake currency | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user