Freqtrade Strategy

SwingHighToSky

15m candlesHyperopt-generatedSpot, long only

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

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

SwingHighToSky account balance compared with holding Bitcoin$0$1,000$2,000$3,000$4,000JulOctJan 2024AprJulOctJan 2025AprSwingHighToSky $1,087BTC hold $3,880
Account balance from $1,000 (closed trades, daily). Dashed line: $1,000 held in BTC over the same days.
Total return+8.7%$1,087 final balance
Max drawdown37.9%11 Apr 2024 to 5 Aug 2024
Win rate71.3%970 wins / 391 losses
Profit factor1.07Gross wins ÷ gross losses
Trades1,3611.9 per day
Average trade+0.03%after fees
Average hold1d 20hwinners 1d 6h, losers 3d 8h
Annualised (CAGR)+4.3%Sharpe 0.28 · Sortino 0.16

How SwingHighToSky trades

SwingHighToSky buys when a 72-period CCI is below -175 and a 36-period RSI is below 90, and sells when a 66-period CCI is above -106 and a 45-period RSI is above 88. All of these numbers come from hyperopt.

An RSI threshold of 90 for buying is almost always true, so the CCI condition decides entries on its own. This is another strategy whose parameters were fitted rather than designed.

Rules at a glance

Indicators
CCI 72, RSI 36, CCI 66, RSI 45
Take-profit (minimal ROI)
27.06% from entry; 8.53% after 33m; 4.093% after 1h 4m; 0% after 4h 4m
Stoploss
−34.34%
Trailing stop
Off
Exit signal
Used

Results by month

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

JFMAMJJASOND2023-92+17+6+0+32+68+942024+46+66+119-172+32+8-110-232+16+24+173+582025+38-147+2+11+32

Results by coin

PairTradesWin rateProfit (USDT)Avg. hold
LINK/USDT11774.4%+123.551d 5h
XRP/USDT14974.5%+102.761d 18h
BTC/USDT14168.1%+57.062d 19h
DOGE/USDT14571.7%+44.491d 4h
BNB/USDT14878.4%+42.652d 8h
ADA/USDT15375.2%+7.721d 14h
DOT/USDT11665.5%−36.791d 17h
AVAX/USDT12770.9%−42.111d 9h
ETH/USDT13866.7%−57.562d 14h
SOL/USDT12765.4%−154.621d 18h

Why trades closed

Exit reasonTradesWin rateProfit (USDT)
Take-profit (ROI)133972.4%+1,298.29
Still open at end of test50.0%−38.29
Stoploss170.0%−1,172.83

The code

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

Entry rules
def populate_entry_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:

    dataframe.loc[
        (
            (dataframe[f'cci-{self.buy_cciTime.value}'] < self.buy_cci.value) &
            (dataframe[f'rsi-{self.buy_rsiTime.value}'] < self.buy_rsi.value)
        ),
        'enter_long'] = 1

    return dataframe
Exit rules
def populate_exit_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:

    dataframe.loc[
        (
            (dataframe[f'cci-sell-{self.sell_cciTime.value}'] > self.sell_cci.value) &
            (dataframe[f'rsi-sell-{self.sell_rsiTime.value}'] > self.sell_rsi.value)
        ),
        'exit_long'] = 1

    return dataframe
Indicators
def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:

    for val in self.buy_cciTime.range:
        dataframe[f'cci-{val}'] = ta.CCI(dataframe, timeperiod=val)

    for val in self.sell_cciTime.range:
        dataframe[f'cci-sell-{val}'] = ta.CCI(dataframe, timeperiod=val)

    for val in self.buy_rsiTime.range:
        dataframe[f'rsi-{val}'] = ta.RSI(dataframe, timeperiod=val)

    for val in self.sell_rsiTime.range:
        dataframe[f'rsi-sell-{val}'] = ta.RSI(dataframe, timeperiod=val)

    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 15m --timerange 20230501-20250530
freqtrade backtesting --strategy SwingHighToSky --timeframe 15m \
  --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.