Timeframe
5m
Direction
Long Only
Stoploss
-10.0%
Trailing Stop
Yes
ROI
0m: 10.0%, 30m: 5.0%, 60m: 2.0%, 120m: 0.0%
Interface Version
N/A
Startup Candles
50
Indicators
4
freqtrade/freqtrade-strategies
Strategy 003 author@: Gerald Lonlas github@: https://github.com/freqtrade/freqtrade-strategies
# 파일명: user_data/strategies/OptimalStrategy.py
from freqtrade.strategy import IStrategy
import pandas as pd
import talib.abstract as ta
class OptimalStrategy(IStrategy):
# 거래 시간 프레임 및 초기 캔들 수
timeframe = '5m'
startup_candle_count = 50
# ROI (이익 실현) 설정: 거래 보유 기간에 따른 목표 이익률
minimal_roi = {
"0": 0.10, # 즉시 10% 이익 시 실현
"30": 0.05, # 30분 이후 5% 이익 시 실현
"60": 0.02, # 60분 이후 2% 이익 시 실현
"120": 0 # 2시간 이후에는 목표 없음(트레일링 스탑 활용)
}
# 고정 손절 설정: 10% 손실 시 종료
stoploss = -0.10
# 트레일링 스탑 설정: 이익 2% 도달 시 활성화, 0.5% 하락 시 청산
trailing_stop = True
trailing_stop_positive = 0.02
trailing_stop_positive_offset = 0.025
trailing_only_offset_is_reached = True
# Deprecated 옵션 변경: sell_profit_only -> exit_profit_only
exit_profit_only = False
# 추가 매도 신호 사용
use_exit_signal = True
ignore_roi_if_entry_signal = True
def populate_indicators(self, dataframe: pd.DataFrame, metadata: dict) -> pd.DataFrame:
"""
매매 신호 생성을 위한 기술적 지표 계산
"""
# 단기, 장기 EMA 계산 (추세 확인)
dataframe['ema_fast'] = ta.EMA(dataframe, timeperiod=12)
dataframe['ema_slow'] = ta.EMA(dataframe, timeperiod=26)
# ADX (추세 강도 측정)
dataframe['adx'] = ta.ADX(dataframe, timeperiod=14)
# RSI (모멘텀 및 과매수/과매도 판단)
dataframe['rsi'] = ta.RSI(dataframe, timeperiod=14)
# Bollinger Bands 하한선 (딥스 감지)
bollinger = ta.BBANDS(dataframe, timeperiod=20, nbdevup=2.0, nbdevdn=2.0)
dataframe['bb_lower'] = bollinger['lowerband']
return dataframe
def populate_entry_trend(self, dataframe: pd.DataFrame, metadata: dict) -> pd.DataFrame:
"""
진입(매수) 신호 생성:
- 상승 추세에서 가격이 일시적으로 하락(딥스)하거나 모멘텀이 강할 경우 진입
"""
dataframe.loc[:, 'buy'] = 0
# 상승 추세: 단기 EMA가 장기 EMA 위에 있으며, ADX가 25 이상인 경우
uptrend = (dataframe['ema_fast'] > dataframe['ema_slow']) & (dataframe['adx'] > 25)
# 딥스 조건: 가격이 Bollinger 하한선 이하이거나 RSI가 30 미만인 경우
dip = (dataframe['close'] < dataframe['bb_lower']) | (dataframe['rsi'] < 30)
# 모멘텀 돌파 조건: 단기 EMA > 장기 EMA 이면서 RSI가 70 이상인 경우
momentum = (dataframe['ema_fast'] > dataframe['ema_slow']) & (dataframe['rsi'] > 70)
entry_condition = (uptrend & dip) | momentum
dataframe.loc[entry_condition, 'buy'] = 1
return dataframe
def populate_exit_trend(self, dataframe: pd.DataFrame, metadata: dict) -> pd.DataFrame:
"""
청산(매도) 신호 생성:
- 추세 반전, 과매수 상황 또는 가격 급락 시 청산
"""
dataframe.loc[:, 'sell'] = 0
# 추세 반전: 단기 EMA가 장기 EMA 아래로 교차하는 경우
trend_reversal = dataframe['ema_fast'] < dataframe['ema_slow']
# 과매수: RSI가 80 이상인 경우
rsi_overbought = dataframe['rsi'] > 80
# 가격 급락: 가격이 단기 EMA의 98% 이하로 떨어진 경우
price_crash = dataframe['close'] < dataframe['ema_slow'] * 0.98
exit_condition = trend_reversal | rsi_overbought | price_crash
dataframe.loc[exit_condition, 'sell'] = 1
return dataframe