Freqtrade Strategy

HourBasedStrategy

1h candlesTime of daySpot, long only

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

HourBasedStrategy turned $1,000 into $475 (−52.5%) over 729 days, while holding Bitcoin returned +288.1% and an equal mix of the ten coins +194.8%. Its worst drawdown was a severe 69.7%, deep enough that most people would have switched it off. With a 64% win rate and a profit factor of 0.85, losses outweighed gains.

HourBasedStrategy account balance compared with holding Bitcoin$0$1,000$2,000$3,000$4,000JulOctJan 2024AprJulOctJan 2025AprHourBasedStrategy $475BTC hold $3,880
Account balance from $1,000 (closed trades, daily). Dashed line: $1,000 held in BTC over the same days.
Total return−52.5%$475 final balance
Max drawdown69.7%26 Dec 2023 to 9 Apr 2025
Win rate63.7%624 wins / 354 losses
Profit factor0.85Gross wins ÷ gross losses
Trades9791.3 per day
Average trade−0.27%after fees
Average hold2d 4hwinners 1d 15h, losers 3d 2h
Annualised (CAGR)−31.1%Sharpe -1.25 · Sortino -1.36

How HourBasedStrategy trades

HourBasedStrategy uses no indicators at all. It enters during one window of UTC hours and exits during another, with both windows chosen by hyperopt. A stepped take-profit and a 10% stoploss limit each trade.

This is a teaching example of how hyperopt can find patterns in noise. Any edge from trading by the clock should be confirmed on data the optimiser never saw.

Rules at a glance

Indicators
Hour of day (UTC)
Take-profit (minimal ROI)
52.8% from entry; 11.3% after 2h 49m; 8.9% after 8h 48m; 0% after 1d 6h
Stoploss
−10%
Trailing stop
Off
Exit signal
Used

Results by month

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

JFMAMJJASOND2023-68+180-247+21+92+23+1832024-296+138+33-509+58-80+47-135+38-8+57-682025+36-121+12+15+74

Results by coin

PairTradesWin rateProfit (USDT)Avg. hold
SOL/USDT24665.4%+109.941d 14h
BTC/USDT21569.3%+53.682d 14h
BNB/USDT9369.9%+11.923d 8h
XRP/USDT9359.1%−4.652d 3h
ETH/USDT22864.5%−48.072d 6h
DOT/USDT60.0%−81.492d 1h
LINK/USDT616.7%−101.8611h 40m
AVAX/USDT1030.0%−101.908h 24m
DOGE/USDT2441.7%−142.471d 5h
ADA/USDT5856.9%−220.281d 22h

Why trades closed

Exit reasonTradesWin rateProfit (USDT)
Take-profit (ROI)80577.5%+2,997.81
Still open at end of test20.0%−19.75
Stoploss1720.0%−3,503.25

The code

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

Entry rules
def populate_entry_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
    dataframe.loc[
        (
            (dataframe['hour'].between(self.buy_hour_min.value, self.buy_hour_max.value))
        ),
        'enter_long'] = 1

    return dataframe
Exit rules
def populate_exit_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
    dataframe.loc[
        (
            (dataframe['hour'].between(self.sell_hour_min.value, self.sell_hour_max.value))
        ),
        'exit_long'] = 1
    return dataframe
Indicators
def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
    dataframe['hour'] = dataframe['date'].dt.hour
    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 HourBasedStrategy --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.