Timeframe
1h
Direction
Long Only
Stoploss
-10.0%
Trailing Stop
Yes
ROI
0m: 5.0%, 60m: 2.5%, 120m: 0.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
# -*- coding: utf-8 -*-
"""
Sample trading strategies for Freqtrade.
Provides strategy templates and a manager for listing/selecting strategies.
"""
from pathlib import Path
from typing import Dict, List
STRATEGY_DIR = Path(__file__).parent.parent / "user_data" / "strategies"
STRATEGY_TEMPLATES: Dict[str, dict] = {
"SMAcrossover": {
"description": "Simple Moving Average crossover strategy using SMA 50/200",
"timeframe": "1h",
"indicators": ["SMA50", "SMA200"],
"buy_logic": "SMA50 crosses above SMA200 (golden cross)",
"sell_logic": "SMA50 crosses below SMA200 (death cross)",
"code": '''
from freqtrade.strategy import IStrategy
import talib.abstract as ta
from pandas import DataFrame
class SMAcrossover(IStrategy):
INTERFACE_VERSION = 3
timeframe = "1h"
minimal_roi = {"0": 0.05, "60": 0.025, "120": 0}
stoploss = -0.10
trailing_stop = True
trailing_stop_positive = 0.01
def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
dataframe["sma50"] = ta.SMA(dataframe, timeperiod=50)
dataframe["sma200"] = ta.SMA(dataframe, timeperiod=200)
return dataframe
def populate_entry_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
dataframe.loc[
(dataframe["sma50"] > dataframe["sma200"]) &
(dataframe["sma50"].shift(1) <= dataframe["sma200"].shift(1)),
"enter_long"
] = 1
return dataframe
def populate_exit_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
dataframe.loc[
(dataframe["sma50"] < dataframe["sma200"]) &
(dataframe["sma50"].shift(1) >= dataframe["sma200"].shift(1)),
"exit_long"
] = 1
return dataframe
''',
},
"RSIbounce": {
"description": "RSI oversold bounce strategy with volume confirmation",
"timeframe": "15m",
"indicators": ["RSI14", "Volume SMA"],
"buy_logic": "RSI < 30 and volume > 1.5x average",
"sell_logic": "RSI > 70 or take-profit at 3%",
"code": '''
from freqtrade.strategy import IStrategy
import talib.abstract as ta
from pandas import DataFrame
class RSIbounce(IStrategy):
INTERFACE_VERSION = 3
timeframe = "15m"
minimal_roi = {"0": 0.03, "30": 0.015, "60": 0}
stoploss = -0.05
def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
dataframe["rsi"] = ta.RSI(dataframe, timeperiod=14)
dataframe["volume_sma"] = ta.SMA(dataframe["volume"], timeperiod=20)
return dataframe
def populate_entry_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
dataframe.loc[
(dataframe["rsi"] < 30) &
(dataframe["volume"] > dataframe["volume_sma"] * 1.5),
"enter_long"
] = 1
return dataframe
def populate_exit_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
dataframe.loc[
(dataframe["rsi"] > 70),
"exit_long"
] = 1
return dataframe
''',
},
"BollingerBreakout": {
"description": "Bollinger Bands breakout with MACD confirmation",
"timeframe": "1h",
"indicators": ["Bollinger Bands", "MACD"],
"buy_logic": "Price closes below lower band and MACD histogram turns positive",
"sell_logic": "Price reaches upper band or MACD histogram turns negative",
"code": '''
from freqtrade.strategy import IStrategy
import talib.abstract as ta
from pandas import DataFrame
class BollingerBreakout(IStrategy):
INTERFACE_VERSION = 3
timeframe = "1h"
minimal_roi = {"0": 0.04, "60": 0.02, "120": 0}
stoploss = -0.08
trailing_stop = True
trailing_stop_positive = 0.015
def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
bb = ta.BBANDS(dataframe, timeperiod=20, nbdevup=2.0, nbdevdn=2.0)
dataframe["bb_upper"] = bb["upperband"]
dataframe["bb_middle"] = bb["middleband"]
dataframe["bb_lower"] = bb["lowerband"]
macd = ta.MACD(dataframe, fastperiod=12, slowperiod=26, signalperiod=9)
dataframe["macd"] = macd["macd"]
dataframe["macdsignal"] = macd["macdsignal"]
dataframe["macdhist"] = macd["macdhist"]
return dataframe
def populate_entry_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
dataframe.loc[
(dataframe["close"] < dataframe["bb_lower"]) &
(dataframe["macdhist"] > 0) &
(dataframe["macdhist"].shift(1) <= 0),
"enter_long"
] = 1
return dataframe
def populate_exit_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
dataframe.loc[
(dataframe["close"] > dataframe["bb_upper"]) |
((dataframe["macdhist"] < 0) & (dataframe["macdhist"].shift(1) >= 0)),
"exit_long"
] = 1
return dataframe
''',
},
}
def list_strategies() -> List[dict]:
result = []
for name, meta in STRATEGY_TEMPLATES.items():
result.append({
"name": name,
"description": meta["description"],
"timeframe": meta["timeframe"],
"indicators": meta["indicators"],
})
return result
def get_strategy_code(name: str) -> str:
template = STRATEGY_TEMPLATES.get(name)
if not template:
return ""
return template["code"].strip()
def export_strategy(name: str, output_dir: Path = STRATEGY_DIR) -> bool:
code = get_strategy_code(name)
if not code:
return False
output_dir.mkdir(parents=True, exist_ok=True)
target = output_dir / f"{name}.py"
try:
target.write_text(code, encoding="utf-8")
return True
except OSError:
return False