Timeframe
5m
Direction
Long & Short
Stoploss
-2.0%
Trailing Stop
Yes
ROI
0m: 5.0%, 60m: 3.0%, 120m: 2.0%
Interface Version
3
Startup Candles
N/A
Indicators
4
freqtrade/freqtrade-strategies
Strategy 003 author@: Gerald Lonlas github@: https://github.com/freqtrade/freqtrade-strategies
from freqtrade.strategy import IStrategy, IntParameter, merge_informative_pair
from pandas import DataFrame
import talib.abstract as ta
class TrendFollowStrategy(IStrategy):
INTERFACE_VERSION = 3
timeframe = "5m"
can_short = True
stoploss = -0.02
trailing_stop = True
trailing_stop_positive = 0.01
trailing_stop_positive_offset = 0.015
trailing_only_offset_is_reached = True
minimal_roi = {
"0": 0.05,
"60": 0.03,
"120": 0.02
}
ema_fast = IntParameter(5, 15, default=9, space="buy")
ema_slow = IntParameter(18, 30, default=21, space="buy")
rsi_long_min = IntParameter(35, 55, default=40, space="buy")
rsi_long_max = IntParameter(60, 75, default=70, space="buy")
rsi_short_min = IntParameter(45, 55, default=50, space="sell")
rsi_short_max = IntParameter(60, 70, default=65, space="sell")
adx_threshold = IntParameter(15, 30, default=20, space="buy")
startup_candle_count: int = 100
def informative_pairs(self):
pairs = self.dp.current_whitelist()
return [(pair, "1h") for pair in pairs]
def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
# --- 5m indicators ---
dataframe["ema_fast"] = ta.EMA(dataframe, timeperiod=self.ema_fast.value)
dataframe["ema_slow"] = ta.EMA(dataframe, timeperiod=self.ema_slow.value)
macd = ta.MACD(dataframe, fastperiod=12, slowperiod=26, signalperiod=9)
dataframe["macd"] = macd["macd"]
dataframe["macd_signal"] = macd["macdsignal"]
dataframe["macd_hist"] = macd["macdhist"]
dataframe["rsi"] = ta.RSI(dataframe, timeperiod=14)
dataframe["adx"] = ta.ADX(dataframe, timeperiod=14)
# --- 1h trend filter ---
informative_1h = self.dp.get_pair_dataframe(
pair=metadata["pair"], timeframe="1h"
)
informative_1h["ema_1h_fast"] = ta.EMA(informative_1h, timeperiod=9)
informative_1h["ema_1h_slow"] = ta.EMA(informative_1h, timeperiod=21)
informative_1h["trend_up"] = (
informative_1h["ema_1h_fast"] > informative_1h["ema_1h_slow"]
).astype(int)
dataframe = merge_informative_pair(
dataframe, informative_1h, self.timeframe, "1h", ffill=True
)
return dataframe
def populate_entry_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
# LONG
dataframe.loc[
(
(dataframe["trend_up_1h"] == 1) &
(dataframe["ema_fast"] > dataframe["ema_slow"]) &
(dataframe["ema_fast"].shift(1) <= dataframe["ema_slow"].shift(1)) &
(dataframe["macd_hist"] > 0) &
(dataframe["macd_hist"].shift(1) <= 0) &
(dataframe["rsi"] >= self.rsi_long_min.value) &
(dataframe["rsi"] <= self.rsi_long_max.value) &
(dataframe["adx"] > self.adx_threshold.value) &
(dataframe["volume"] > 0)
),
["enter_long", "enter_tag"]
] = 1, "ema_macd_long"
# SHORT
dataframe.loc[
(
(dataframe["trend_up_1h"] == 0) &
(dataframe["ema_fast"] < dataframe["ema_slow"]) &
(dataframe["ema_fast"].shift(1) >= dataframe["ema_slow"].shift(1)) &
(dataframe["macd_hist"] < 0) &
(dataframe["macd_hist"].shift(1) >= 0) &
(dataframe["rsi"] >= self.rsi_short_min.value) &
(dataframe["rsi"] <= self.rsi_short_max.value) &
(dataframe["adx"] > self.adx_threshold.value) &
(dataframe["volume"] > 0)
),
["enter_short", "enter_tag"]
] = 1, "ema_macd_short"
return dataframe
def populate_exit_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
return dataframe