Freqtrade Strategy

ADXMomentum

1h candlesTrend followingSpot, long only

Tested 1 Jun 2023 – 30 May 2025
Rank 8 of 27 by return

ADXMomentum turned $1,000 into $1,325 (+32.5%) over 729 days, while holding Bitcoin returned +288.1% and an equal mix of the ten coins +194.8%. Its worst drawdown was 28.9%, a substantial dip to sit through. It won 86% of trades with small targets; a profit factor of 1.06 shows how thin that edge is.

ADXMomentum account balance compared with holding Bitcoin$0$1,000$2,000$3,000$4,000JulOctJan 2024AprJulOctJan 2025AprADXMomentum $1,325BTC hold $3,880
Account balance from $1,000 (closed trades, daily). Dashed line: $1,000 held in BTC over the same days.
Total return+32.5%$1,325 final balance
Max drawdown28.9%4 Dec 2024 to 9 Apr 2025
Win rate85.8%2,937 wins / 488 losses
Profit factor1.06Gross wins ÷ gross losses
Trades3,4254.7 per day
Average trade+0.05%after fees
Average hold12h 47mwinners 8h 10m, losers 1d 16h
Annualised (CAGR)+15.1%Sharpe 1.59 · Sortino 1.23

How ADXMomentum trades

ADXMomentum waits for a trend that is both strong and pointing up. It enters when ADX is above 25, 14-period momentum is positive and the +DI line sits above both 25 and the -DI line. The mirror image of that condition (momentum turning negative while -DI takes over) closes the trade.

The 1% take-profit at minute zero does most of the work: about 86% of trades close through ROI long before the trend-based exit fires, which explains the very high win rate. Losing trades are mostly closed by the exit signal; the wide 25% stoploss was rarely reached.

Rules at a glance

Indicators
ADX, +DI / -DI, Momentum
Take-profit (minimal ROI)
1% from entry
Stoploss
−25%
Trailing stop
Off
Exit signal
Used

Results by month

Profit or loss in USDT for trades closed in each month.

JFMAMJJASOND2023-43-55-161+38+220-39+892024-138+192+43-153+63-116-6-13+80-32+505-1302025+88-177-95+20+141

Results by coin

PairTradesWin rateProfit (USDT)Avg. hold
LINK/USDT32191.3%+152.389h 5m
SOL/USDT45589.7%+103.0312h 33m
ADA/USDT38388.0%+76.039h 50m
XRP/USDT35286.1%+57.5610h 30m
AVAX/USDT36189.8%+56.689h 21m
DOGE/USDT40688.2%+29.659h 6m
BTC/USDT33876.6%−2.6720h 6m
BNB/USDT26180.5%−10.1519h 6m
ETH/USDT33379.6%−55.8917h 57m
DOT/USDT21583.7%−81.9513h 25m

Why trades closed

Exit reasonTradesWin rateProfit (USDT)
Take-profit (ROI)2937100.0%+5,879.17
Still open at end of test10.0%−4.40
Stoploss20.0%−100.69
Exit signal4850.0%−5,449.42

The code

ADXMomentum comes from the community freqtrade-strategies repository (GPL-3.0). These are the parts that decide when it trades; the full file is 69 lines.

Entry rules
def populate_entry_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
    dataframe.loc[
        (
                (dataframe['adx'] > 25) &
                (dataframe['mom'] > 0) &
                (dataframe['plus_di'] > 25) &
                (dataframe['plus_di'] > dataframe['minus_di'])

        ),
        'enter_long'] = 1
    return dataframe
Exit rules
def populate_exit_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
    dataframe.loc[
        (
                (dataframe['adx'] > 25) &
                (dataframe['mom'] < 0) &
                (dataframe['minus_di'] > 25) &
                (dataframe['plus_di'] < dataframe['minus_di'])

        ),
        'exit_long'] = 1
    return dataframe
Indicators
def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
    dataframe['adx'] = ta.ADX(dataframe, timeperiod=14)
    dataframe['plus_di'] = ta.PLUS_DI(dataframe, timeperiod=25)
    dataframe['minus_di'] = ta.MINUS_DI(dataframe, timeperiod=25)
    dataframe['sar'] = ta.SAR(dataframe)
    dataframe['mom'] = ta.MOM(dataframe, timeperiod=14)

    return dataframe

Reproduce this test

With freqtrade installed (see our Docker guide), download the data and run the same backtest:

freqtrade download-data --exchange binance --pairs ADA/USDT AVAX/USDT BNB/USDT BTC/USDT DOGE/USDT DOT/USDT ETH/USDT LINK/USDT SOL/USDT XRP/USDT --timeframes 1h --timerange 20230501-20250530
freqtrade backtesting --strategy ADXMomentum --timeframe 1h \
  --timerange 20230601-20250530 --dry-run-wallet 1000 --stake-amount 200 --max-open-trades 5 --fee 0.001

Results can differ slightly with a different data source or freqtrade version. See how we test.