Timeframe
5m
Direction
Long Only
Stoploss
-2.0%
Trailing Stop
Yes
ROI
0m: 1.0%, 30m: 0.5%, 90m: 0.0%
Interface Version
N/A
Startup Candles
240
Indicators
5
freqtrade/freqtrade-strategies
Strategy 003 author@: Gerald Lonlas github@: https://github.com/freqtrade/freqtrade-strategies
import logging
from typing import Any, Dict, List, Optional, Tuple
import numpy as np
import pandas as pd
from pandas import DataFrame
from datetime import datetime, timedelta
from freqtrade.strategy import IStrategy, IntParameter, DecimalParameter
from freqtrade.strategy.parameters import CategoricalParameter
from freqtrade.persistence import Trade
from freqtrade.exchange import timeframe_to_minutes
import talib.abstract as ta
import pandas_ta as pta
from freqtrade.strategy import DecimalParameter, IntParameter, CategoricalParameter
import logging
from collections import defaultdict
import warnings
warnings.filterwarnings("ignore")
import talib as tal
import pandas_ta as pta
logger = logging.getLogger(__name__)
class NewsHeliusBitqueryML_Hyperopt(IStrategy):
timeframe = "5m"
can_short = False
process_only_new_candles = True
startup_candle_count = 240
use_exit_signal = True
exit_profit_only = False
ignore_roi_if_entry_signal = False
position_adjustment_enable = False
order_time_in_force = {
"entry": "GTC",
"exit": "GTC"
}
order_types = {
"entry": "limit",
"exit": "limit",
"stoploss": "limit",
"stoploss_on_exchange": False,
"stoploss_on_exchange_interval": 60,
}
# Параметры для гипероптимизации ROI
minimal_roi = {
"0": 0.01,
"30": 0.005,
"90": 0.0
}
stoploss = -0.02
trailing_stop = True
trailing_stop_positive = 0.004
trailing_stop_positive_offset = 0.009
trailing_only_offset_is_reached = True
ignore_buying_expired_candle_after = 1
# Параметры для гипероптимизации
buy_params = {
"vol_min": 0.002,
"rsi_long_th": 45,
"adx_min": 14,
"ema_fast": 12,
"ema_slow": 26,
"rsi_period": 14,
"macd_fast": 12,
"macd_slow": 26,
"macd_signal": 9,
"atr_period": 14
}
sell_params = {
"rsi_exit_long": 70,
"ema_exit_long": True
}
# Параметры для гипероптимизации ROI
roi_params = {
"roi_0": 0.01,
"roi_30": 0.005,
"roi_90": 0.0
}
# Параметры для гипероптимизации Stoploss
stoploss_params = {
"stoploss": -0.02
}
# Параметры для гипероптимизации Trailing Stop
trailing_params = {
"trailing_stop": True,
"trailing_stop_positive": 0.004,
"trailing_stop_positive_offset": 0.009,
"trailing_only_offset_is_reached": True
}
def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
df = dataframe.copy()
# --- EMA, MACD ---
ema_fast = df["close"].ewm(span=self.buy_params['ema_fast'], adjust=False).mean()
ema_slow = df["close"].ewm(span=self.buy_params['ema_slow'], adjust=False).mean()
df["macd"] = ema_fast - ema_slow
df["macd_sig"] = df["macd"].ewm(span=self.buy_params['macd_signal'], adjust=False).mean()
df["macd_hist"] = df["macd"] - df["macd_sig"]
# Дополнительные EMA для анализа тренда
df["ema50"] = df["close"].ewm(span=50, adjust=False).mean()
df["ema200"] = df["close"].ewm(span=200, adjust=False).mean()
# Сохраняем быстрые EMA для совместимости с существующим кодом
df['ema_fast'] = ema_fast
df['ema_slow'] = ema_slow
# --- RSI(14) ---
delta = df["close"].diff()
gain = delta.clip(lower=0)
loss = -delta.clip(upper=0)
avg_gain = gain.ewm(alpha=1/self.buy_params['rsi_period'], min_periods=self.buy_params['rsi_period'], adjust=False).mean()
avg_loss = loss.ewm(alpha=1/self.buy_params['rsi_period'], min_periods=self.buy_params['rsi_period'], adjust=False).mean()
rs = avg_gain / (avg_loss + 1e-10)
df["rsi"] = 100 - (100 / (1 + rs))
# --- ATR(14) ---
prev_close = df["close"].shift()
tr = pd.concat([
(df["high"] - df["low"]),
(df["high"] - prev_close).abs(),
(df["low"] - prev_close).abs()
], axis=1).max(axis=1)
df["atr"] = tr.ewm(alpha=1/self.buy_params['atr_period'], min_periods=self.buy_params['atr_period'], adjust=False).mean()
# ADX calculation (simplified)
df['adx'] = df['atr'].rolling(window=14).mean() # Simplified ADX
# Volume fraction
df['vol_frac'] = df['volume'] / df['volume'].rolling(window=20).mean()
# Подчищаем и убеждаемся, что всё числовое
for c in ["macd", "macd_sig", "macd_hist", "ema50", "ema200", "rsi", "atr", "ema_fast", "ema_slow"]:
df[c] = pd.to_numeric(df[c], errors="coerce")
df.ffill(inplace=True)
df.bfill(inplace=True)
return df
def populate_entry_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
df = dataframe.copy()
vol_min = self.buy_params['vol_min']
rsi_long_th = self.buy_params['rsi_long_th']
adx_min = self.buy_params['adx_min']
long_cond = (
(df['ema_fast'] > df['ema_slow']) &
(df['vol_frac'] > vol_min) &
(df['macd'] > df['macd_sig']) &
(df['adx'] >= adx_min) &
(df['rsi'].shift(1) < rsi_long_th) & (df['rsi'] >= rsi_long_th)
)
df['enter_long'] = long_cond.astype(int)
return df
def populate_exit_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
df = dataframe.copy()
rsi_exit_long = self.sell_params['rsi_exit_long']
ema_exit_long = self.sell_params['ema_exit_long']
exit_long = (
(df['rsi'] > rsi_exit_long) |
(ema_exit_long and df['close'] < df['ema_fast'])
)
df['exit_long'] = exit_long.astype(int)
return df
# Методы для гипероптимизации ROI
def custom_roi(self, dataframe: DataFrame, trade: Trade, current_time: datetime, **kwargs) -> float:
# Динамический ROI на основе времени удержания позиции
open_minutes = (current_time - trade.open_date_utc).total_seconds() / 60
if open_minutes <= 30:
return self.roi_params['roi_0']
elif open_minutes <= 90:
return self.roi_params['roi_30']
else:
return self.roi_params['roi_90']
# Методы для гипероптимизации Stoploss
def custom_stoploss(self, pair: str, trade: Trade, current_time: datetime, current_rate: float, current_profit: float, **kwargs) -> float:
return self.stoploss_params['stoploss']
# Методы для гипероптимизации Trailing Stop
def custom_trailing_stop(self, pair: str, trade: Trade, current_time: datetime, current_rate: float, current_profit: float, **kwargs) -> float:
if not self.trailing_params['trailing_stop']:
return 0
if current_profit > self.trailing_params['trailing_stop_positive_offset']:
return self.trailing_params['trailing_stop_positive']
return 0
@property
def protections(self):
return [
{"method": "CooldownPeriod", "stop_duration_candles": 5},
{"method": "StoplossGuard", "lookback_period_candles": 288,
"stop_duration_candles": 30, "only_per_pair": False, "trade_limit": 2},
{"method": "MaxDrawdown", "lookback_period_candles": 288,
"stop_duration_candles": 60, "max_allowed_drawdown": 8,
"only_per_pair": False}
]