Simple Moving Average Crossover Strategy - 20/50 SMA
Timeframe
1h
Direction
Long Only
Stoploss
-5.0%
Trailing Stop
Yes
ROI
0m: 10.0%, 30m: 5.0%, 60m: 2.5%, 120m: 1.0%
Interface Version
3
Startup Candles
N/A
Indicators
1
freqtrade/freqtrade-strategies
this is an example class, implementing a PSAR based trailing stop loss you are supposed to take the `custom_stoploss()` and `populate_indicators()` parts and adapt it to your own strategy
freqtrade/freqtrade-strategies
freqtrade/freqtrade-strategies
Strategy 003 author@: Gerald Lonlas github@: https://github.com/freqtrade/freqtrade-strategies
"""
Simple Moving Average Crossover Strategy - 20/50 SMA
Generated by TradingView Strategy Research Lab
Date: 2026-01-19 13:42:17
Original Strategy: SMA Crossover
Backtest Results:
- Win Rate: 55.0%
- Profit Factor: 1.80
- Max Drawdown: 12.0%
"""
from freqtrade.strategy import IStrategy, IntParameter, DecimalParameter
from pandas import DataFrame
import talib.abstract as ta
class SmaCrossoverStrategy(IStrategy):
"""
Simple Moving Average Crossover Strategy - 20/50 SMA
"""
# 전략 설정
INTERFACE_VERSION = 3
# 타임프레임
timeframe = '1h'
# 리스크 관리
stoploss = -0.05
trailing_stop = True
trailing_stop_positive = 0.01
trailing_stop_positive_offset = 0.02
trailing_only_offset_is_reached = True
# ROI 테이블 (시간별 목표 수익률)
minimal_roi = {
"0": 0.10, # 즉시 10% 수익 시 청산
"30": 0.05, # 30분 후 5% 수익 시 청산
"60": 0.025, # 1시간 후 2.5% 수익 시 청산
"120": 0.01, # 2시간 후 1% 수익 시 청산
}
# 주문 설정
order_types = {
'entry': 'limit',
'exit': 'limit',
'stoploss': 'market',
'stoploss_on_exchange': True
}
# 최적화 가능한 파라미터
sma_fast_period = IntParameter(10, 40, default=20, space='buy')
sma_slow_period = IntParameter(40, 70, default=50, space='buy')
def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
"""
지표 계산
"""
dataframe['sma_fast'] = ta.SMA(dataframe["close"], timeperiod=20)
dataframe['sma_slow'] = ta.SMA(dataframe["close"], timeperiod=50)
return dataframe
def populate_entry_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
"""
진입 조건
"""
dataframe.loc[
(dataframe['sma_fast'] > dataframe['sma_slow'])
& (dataframe['sma_fast'].shift(1) <= dataframe['sma_slow'].shift(1))
& (dataframe['volume'] > dataframe['volume'].rolling(20).mean())
,
'enter_long'] = 1
return dataframe
def populate_exit_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
"""
청산 조건
"""
dataframe.loc[
(dataframe['sma_fast'] < dataframe['sma_slow'])
& (dataframe['sma_fast'].shift(1) >= dataframe['sma_slow'].shift(1))
,
'exit_long'] = 1
return dataframe