Strategy adapted from paper: http://arxiv.org/abs/2511.00665
Timeframe
5m
Direction
Long Only
Stoploss
-9900.0%
Trailing Stop
No
ROI
N/A
Interface Version
3
Startup Candles
N/A
Indicators
2
freqtrade/freqtrade-strategies
from datetime import datetime
import talib.abstract as ta
from freqtrade.strategy import (
IntParameter,
IStrategy,
)
from pandas import DataFrame
class MacdAdxStrategy(IStrategy):
"""
Strategy adapted from paper: http://arxiv.org/abs/2511.00665
"""
# Strategy interface version - allow new iterations of the strategy interface.
# Check the documentation or the Sample strategy to get the latest version.
INTERFACE_VERSION = 3
# Optimal timeframe for the strategy.
timeframe = "5m"
# Can this strategy go short?
can_short: bool = False
# Minimal ROI designed for the strategy.
# This attribute will be overridden if the config file contains "minimal_roi".
minimal_roi = {}
# Optimal stoploss designed for the strategy.
# This attribute will be overridden if the config file contains "stoploss".
stoploss = -99
# Trailing stoploss
trailing_stop = False
# trailing_only_offset_is_reached = False
# trailing_stop_positive = 0.01
# trailing_stop_positive_offset = 0.0 # Disabled / not configured
# Run "populate_indicators()" only for new candle.
process_only_new_candles = True
# These values can be overridden in the config.
use_exit_signal = True
exit_profit_only = False
ignore_roi_if_entry_signal = False
# Number of candles the strategy requires before producing valid signals
startup_candle_count: int = 30
# Strategy parameters
macdFast = IntParameter(8, 15, default=15, space="buy")
macdSlow = IntParameter(20, 30, default=26, space="buy")
macdSignal = IntParameter(7, 15, default=9, space="buy")
adxPeriod = IntParameter(10, 20, default=15, space="buy")
def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
macd = ta.MACD(
dataframe,
fastperiod=self.macdFast.value,
slowperiod=self.macdSlow.value,
signalperiod=self.macdSignal.value
)
dataframe["macd"] = macd["macd"]
dataframe["macdsignal"] = macd["macdsignal"]
dataframe["adx"] = ta.ADX(dataframe, timeperiod=self.adxPeriod.value)
dataframe["mean-volume"] = dataframe["volume"].rolling(20).mean()
return dataframe
def populate_entry_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
dataframe.loc[
(
(dataframe['macd'] > dataframe['macdsignal']) &
(dataframe['adx'] > 25) &
(dataframe["mean-volume"] > 0.75)
),
"enter_long",
] = 1
return dataframe
def populate_exit_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
dataframe.loc[
(
(dataframe['macd'] < dataframe['macdsignal']) &
(dataframe['adx'] > 25) &
(dataframe["mean-volume"] > 0.75)
),
"exit_long",
] = 1
return dataframe
def confirm_trade_entry(self, pair: str, order_type: str, amount: float, rate: float,
time_in_force: str, current_time: datetime, entry_tag: str | None,
side: str, **kwargs) -> bool:
dataframe, _ = self.dp.get_analyzed_dataframe(pair, self.timeframe)
last_close = dataframe.iloc[-1]["close"]
max_deviation = 0.01 # 1% deviation allowed
deviation = abs(rate - last_close) / last_close
if deviation > max_deviation:
return False
return True