Разрабатываю улучшенную логику входа для трендовой стратегии, которая будет работать на таймфрейме 5 минут. Основная цель — фильтрация ложных сигналов и вход в оптимальной точке.
Ключевые особенности стратегии:
1. Умная точка входа
- Вход при коррекции к EMA9 (в пределах 0.5 ATR)
- Дополнительная проверка положения относительно EMA21
2. Многофакторная фильтрация
- Комбинация ADX, DMI, MACD и объемов
- Требуется выполнение 5 из 6 условий
3. Защитный стоп-лосс
- Рассчитывается на основе ATR и ключевых уровней
- Учитывает как EMA9, так и 20-периодные экстремумы
Пример идеального входа (LONG):
✔ ADX > 25 и +DI > -DI
✔ Цена корректируется к EMA9
✔ Пробит 20-периодный максимум
✔ Объем выше среднего на 50%
✔ MACD гистограмма растет
💬 *Как вам такая логика? Какие параметры стоит доработать?*
Код стратегии:
def strategy(self, df: pd.DataFrame, current_price: float) -> Tuple[str, Optional[float]]:
# Проверка на достаточность данных
if df.empty or len(df) < 50 or current_price == 0.0:
return 'hold', None
# Расчет индикаторов
df = self.calculate_indicators(df)
df = self._calculate_dmi(df)
if df.empty:
return 'hold', None
last = df.iloc[-1]
# EMA 9 и 21 периодов
ema9 = df['close'].ewm(span=9, adjust=False).mean().iloc[-1]
ema21 = df['close'].ewm(span=21, adjust=False).mean().iloc[-1]
# Определение "близости" к EMA9 (0.5 ATR)
atr = df['atr'].iloc[-1]
near_ema9 = abs(current_price - ema9) < atr * 0.5
# Условия тренда
strong_trend = last['adx'] > 25
uptrend = last['plus_di'] > last['minus_di']
downtrend = last['minus_di'] > last['plus_di']
### УСЛОВИЯ ДЛЯ LONG ###
long_conditions = [
strong_trend and uptrend, # Сильный восходящий тренд
current_price > ema21, # Цена выше EMA21
near_ema9 and current_price >= ema9, # Коррекция к EMA9
current_price > df['high'].rolling(20).max().iloc[-1], # Пробитие максимума
df['volume'].iloc[-1] > df['volume'].rolling(20).mean().iloc[-1] * 1.5, # Объем
df['macd_hist'].iloc[-1] > df['macd_hist'].iloc[-2] # Рост MACD
]
### УСЛОВИЯ ДЛЯ SHORT ###
short_conditions = [
strong_trend and downtrend, # Сильный нисходящий тренд
current_price < ema21, # Цена ниже EMA21
near_ema9 and current_price <= ema9, # Коррекция к EMA9
current_price < df['low'].rolling(20).min().iloc[-1], # Пробитие минимума
df['volume'].iloc[-1] > df['volume'].rolling(20).mean().iloc[-1] * 1.5, # Объем
df['macd_hist'].iloc[-1] < df['macd_hist'].iloc[-2] # Падение MACD
]
### ЛОГИКА ВХОДА ###
if sum(long_conditions) >= 5: # 5 из 6 условий
sl = min(ema9, df['low'].rolling(20).min().iloc[-1]) - atr * 0.3
return 'buy', sl
if sum(short_conditions) >= 5: # 5 из 6 условий
sl = max(ema9, df['high'].rolling(20).max().iloc[-1]) + atr * 0.3
return 'sell', sl
return 'hold', None