DISCLAIMER
The codes in this post is just for educational purpose, and not to be used on live trading
In previous posts, we only use 15m timeframe. What if I want to use other timeframes, for example I want to use 30m and 1h timeframes to calculate rsi of them, and add those rsi on entry logic?
First, you need to add new import
from freqtrade.strategy import IStrategy, informative
Then you need to specify the informative timeframes. Remember, the base timeframe must be the lowest of all. So in our example, since we want to use 15m, 30m and 1h timeframes, the base timeframe must be the 15m. 30m and 1h is our informative timeframes. There are 2 ways to define informative. I will use the easiest way, which is using informative decorator. Since I will calculate same indicator on both informative timeframes, I can merge them into 1 function
@informative('30m') @informative('1h') def populate_indicators_inf1(self, dataframe: DataFrame, metadata: dict) -> DataFrame: dataframe['rsi'] = ta.RSI(dataframe, 14) return dataframe
But in case you will calculate different indicators on each of the informative timeframes, you can split them into separate functions. If you are doing it this way, remember that the functions have to have different name definition, otherwise the latter function will override previous functions with same name.
@informative('30m') def populate_indicators_inf1(self, dataframe: DataFrame, metadata: dict) -> DataFrame: dataframe['rsi'] = ta.RSI(dataframe, 14) return dataframe @informative('1h') def populate_indicators_inf2(self, dataframe: DataFrame, metadata: dict) -> DataFrame: dataframe['rsi'] = ta.RSI(dataframe, 14) return dataframe
The code above will create rsi_30m
and rsi_1h
columns to be used on your strategy. Let’s say, you want to add more conditions in your entry logic
def populate_entry_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: dataframe.loc[ qtpylib.crossed_above(dataframe['ema_9'], dataframe['ema_20']) & (dataframe['rsi_30m'] < 50) & (dataframe['rsi_1h'] < 30) & (dataframe['volume'] > 0) , ['enter_long', 'enter_tag'] ] = (1, 'golden cross') return dataframe
The full code will look like this
from freqtrade.strategy import IStrategy, informative from pandas import DataFrame import freqtrade.vendor.qtpylib.indicators as qtpylib import talib.abstract as ta from freqtrade.persistence import Trade from datetime import datetime, timedelta from typing import Optional, Union class strat_template (IStrategy): def version(self) -> str: return "template-v1" INTERFACE_VERSION = 3 minimal_roi = { "0": 0.05 } stoploss = -0.05 timeframe = '15m' process_only_new_candles = True startup_candle_count = 999 use_custom_stoploss = True def custom_stoploss(self, pair: str, trade: 'Trade', current_time: datetime, current_rate: float, current_profit: float, **kwargs) -> float: sl_new = 1 if (current_time - timedelta(minutes=15) >= trade.open_date_utc): dataframe, _ = self.dp.get_analyzed_dataframe(pair, self.timeframe) current_candle = dataframe.iloc[-1].squeeze() current_profit = trade.calc_profit_ratio(current_candle['close']) if (current_profit >= 0.03): sl_new = 0.01 return sl_new def custom_exit(self, pair: str, trade: Trade, current_time: datetime, current_rate: float, current_profit: float, **kwargs) -> Optional[Union[str, bool]]: if ((current_time - timedelta(minutes=15)) >= trade.open_date_utc): dataframe, _ = self.dp.get_analyzed_dataframe(pair, self.timeframe) current_candle = dataframe.iloc[-1].squeeze() current_profit = trade.calc_profit_ratio(current_candle['close']) if (current_profit >= 0): if (current_candle['rsi'] >= 70): return "rsi_overbought" @informative('30m') def populate_indicators_inf1(self, dataframe: DataFrame, metadata: dict) -> DataFrame: dataframe['rsi'] = ta.RSI(dataframe, 14) return dataframe @informative('1h') def populate_indicators_inf2(self, dataframe: DataFrame, metadata: dict) -> DataFrame: dataframe['rsi'] = ta.RSI(dataframe, 14) return dataframe def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame: dataframe['ema_9'] = ta.EMA(dataframe, 9) dataframe['ema_20'] = ta.EMA(dataframe, 20) dataframe['rsi'] = ta.RSI(dataframe, 14) return dataframe def populate_entry_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: dataframe.loc[ qtpylib.crossed_above(dataframe['ema_9'], dataframe['ema_20']) & (dataframe['rsi_30m'] < 50) & (dataframe['rsi_1h'] < 30) & (dataframe['volume'] > 0) , ['enter_long', 'enter_tag'] ] = (1, 'golden cross') return dataframe def populate_exit_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: dataframe.loc[ qtpylib.crossed_below(dataframe['ema_9'], dataframe['ema_20']) & (dataframe['volume'] > 0) , ['exit_long', 'exit_tag'] ] = (1, 'death cross') return dataframe
[…] Previous – Trailing stoploss Next – Using multiple timeframes […]
[…] Previous – Using multiple timeframes Next […]
[…] Using multiple timeframes […]