A Multi-Timeframe RSI Strategy with Moving-Average Entries
Summary
This Freqtrade example calculates a five-period and a 200-period simple moving average alongside relative strength index values on the base timeframe and on two resampled, longer intervals. It enters long when the base-timeframe RSI falls at least 20 points below the longest-interval RSI, subject to a moving-average condition. It exits when the base RSI rises above both resampled RSI values. The strategy also sets a five-minute timeframe, a fixed stop loss, and a small return-on-investment target.
The example provides indicator and signal rules, but no backtest results, transaction-cost analysis, or rationale for the thresholds. Its entry comment calls the setup bearish, while the stated condition has the short moving average at or above the long moving average; that mismatch makes the intended trend filter unclear. The code alone does not show whether resampling avoids look-ahead bias or whether the strategy is profitable across assets and market regimes.
Key ideas
- The strategy compares RSI on the base interval with RSI from two resampled intervals.
- A long entry requires the base RSI to fall well below the longest-interval RSI.
- The entry also applies a short-to-long moving-average condition that conflicts with its bearish comment.
- A long exit occurs when the base RSI exceeds both resampled RSI values.
- No backtest or robustness evidence is included.
Tags
Full text
# MultiRSI.py
```py
# --- Do not remove these libs ---
from freqtrade.strategy import IStrategy
from pandas import DataFrame
# --------------------------------
import talib.abstract as ta
from technical.util import resample_to_interval, resampled_merge
class MultiRSI(IStrategy):
"""
author@: Gert Wohlgemuth
based on work from Creslin
"""
INTERFACE_VERSION: int = 3
minimal_roi = {
"0": 0.01
}
# Optimal stoploss designed for the strategy
stoploss = -0.05
# Optimal timeframe for the strategy
timeframe = '5m'
def get_ticker_indicator(self):
return int(self.timeframe[:-1])
def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
dataframe['sma5'] = ta.SMA(dataframe, timeperiod=5)
dataframe['sma200'] = ta.SMA(dataframe, timeperiod=200)
# resample our dataframes
dataframe_short = resample_to_interval(dataframe, self.get_ticker_indicator() * 2)
dataframe_long = resample_to_interval(dataframe, self.get_ticker_indicator() * 8)
# compute our RSI's
dataframe_short['rsi'] = ta.RSI(dataframe_short, timeperiod=14)
dataframe_long['rsi'] = ta.RSI(dataframe_long, timeperiod=14)
# merge dataframe back together
dataframe = resampled_merge(dataframe, dataframe_short)
dataframe = resampled_merge(dataframe, dataframe_long)
dataframe['rsi'] = ta.RSI(dataframe, timeperiod=14)
dataframe.ffill(inplace=True)
return dataframe
def populate_entry_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
dataframe.loc[
(
# must be bearish
(dataframe['sma5'] >= dataframe['sma200']) &
(dataframe['rsi'] < (dataframe['resample_{}_rsi'.format(self.get_ticker_indicator() * 8)] - 20))
),
'enter_long'] = 1
return dataframe
def populate_exit_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
dataframe.loc[
(
(dataframe['rsi'] > dataframe['resample_{}_rsi'.format(self.get_ticker_indicator()*2)]) &
(dataframe['rsi'] > dataframe['resample_{}_rsi'.format(self.get_ticker_indicator()*8)])
),
'exit_long'] = 1
return dataframe
```Shown in full with attribution under the source's licence. Licence: GPL-3.0
This summary was written by Stratmill's research agent from the original; it is not a copy of the source.