Freqtrade Strategy

MultiMa

4h candlesTrend followingSpot, long only

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

MultiMa turned $1,000 into $1,978 (+97.8%) over 729 days, while holding Bitcoin returned +288.1% and an equal mix of the ten coins +194.8%. Its worst drawdown was a relatively contained 11.1%. It won 67% of trades for a profit factor of 2.43.

MultiMa account balance compared with holding Bitcoin$0$1,000$2,000$3,000$4,000JulOctJan 2024AprJulOctJan 2025AprMultiMa $1,978BTC hold $3,880
Account balance from $1,000 (closed trades, daily). Dashed line: $1,000 held in BTC over the same days.
Total return+97.8%$1,978 final balance
Max drawdown11.1%8 Aug 2023 to 23 Sep 2023
Win rate67.3%165 wins / 80 losses
Profit factor2.43Gross wins ÷ gross losses
Trades2450.3 per day
Average trade+1.99%after fees
Average hold3d 8hwinners 2d 8h, losers 5d 10h
Annualised (CAGR)+40.7%Sharpe 1.76 · Sortino 2.74

How MultiMa trades

MultiMa builds a ladder of triple-exponential moving averages on the 4-hour chart and enters when the averages are stacked in a particular order (four averages, 15 periods apart). It exits when a longer ladder of twelve averages flips the other way.

Slow by design: few trades, long holding times and a 34.5% stoploss. Results depend heavily on a small number of large trends.

Rules at a glance

Indicators
Stacked TEMAs
Take-profit (minimal ROI)
52.3% from entry; 12.3% after 1d 1h; 7.6% after 1d 14h; 0% after 2d 4h
Stoploss
−34.5%
Trailing stop
Off
Exit signal
Used

Results by month

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

JFMAMJJASOND2023+24+180-74-43+149+123+1302024-12+43+117+0+0+0+0-23+37-48+275+1062025+0+0+0+0-4

Results by coin

PairTradesWin rateProfit (USDT)Avg. hold
XRP/USDT2268.2%+215.812d 7h
DOGE/USDT2962.1%+178.222d 15h
SOL/USDT2972.4%+136.782d 6h
ADA/USDT2871.4%+136.252d 21h
AVAX/USDT2661.5%+97.503d 4h
LINK/USDT2080.0%+87.823d 12h
ETH/USDT2075.0%+53.914d 20h
DOT/USDT2770.4%+44.793d 18h
BNB/USDT2653.8%+21.893d 23h
BTC/USDT1861.1%+5.075d 6h

Why trades closed

Exit reasonTradesWin rateProfit (USDT)
Take-profit (ROI)19883.3%+1,662.86
Exit signal470.0%−684.82

The code

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

Entry rules
def populate_entry_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
    conditions = []
    # I used range(self.buy_ma_count.value) instade of self.buy_ma_count.range
    # Cuz it returns range(7,8) but we need range(8) for all modes hyperopt, backtest and etc

    for ma_count in range(self.buy_ma_count.value):
        key = ma_count*self.buy_ma_gap.value
        past_key = (ma_count-1)*self.buy_ma_gap.value
        if past_key > 1 and key in dataframe.keys() and past_key in dataframe.keys():
            conditions.append(dataframe[key] < dataframe[past_key])

    if conditions:
        dataframe.loc[reduce(lambda x, y: x & y, conditions), "enter_long"] = 1
    return dataframe
Exit rules
def populate_exit_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
    conditions = []

    for ma_count in range(self.sell_ma_count.value):
        key = ma_count*self.sell_ma_gap.value
        past_key = (ma_count-1)*self.sell_ma_gap.value
        if past_key > 1 and key in dataframe.keys() and past_key in dataframe.keys():
            conditions.append(dataframe[key] > dataframe[past_key])

    if conditions:
        dataframe.loc[reduce(lambda x, y: x | y, conditions), "exit_long"] = 1
    return dataframe
Indicators
def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
    for count in range(self.count_max):
        for gap in range(self.gap_max):
            if count*gap > 1 and count*gap not in dataframe.keys():
                dataframe[count*gap] = ta.TEMA(
                    dataframe, timeperiod=int(count*gap)
                )
    print(" ", metadata['pair'], end="\t\r")

    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 4h --timerange 20230501-20250530
freqtrade backtesting --strategy MultiMa --timeframe 4h \
  --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.