15 related strategies (⧉ identical code, ≈ similar name)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 | # pragma pylint: disable=missing-docstring, invalid-name, pointless-string-statement # flake8: noqa: F401 # --- Do not remove these libs --- import numpy as np import pandas as pd from pandas import DataFrame from datetime import datetime from typing import Optional, List from freqtrade.strategy import (IStrategy, IntParameter, DecimalParameter, CategoricalParameter) from freqtrade.persistence import Trade import talib.abstract as ta import freqtrade.vendor.qtpylib.indicators as qtpylib class FuturesSwingStrategy(IStrategy): """ This is the final, robust hyperoptable version. It separates static defaults from hyperopt spaces and correctly assigns parameters to the 'buy' and 'sell' spaces for full compatibility. """ INTERFACE_VERSION = 3 timeframe = '4h' can_short: bool = True # --- Static Default Parameters for Backtesting & Initial Validation --- minimal_roi = { "0": 0.862, "1538": 0.312, "3044": 0.1, "7553": 0 } stoploss = -0.282 trailing_stop = True trailing_stop_positive = 0.015 trailing_stop_positive_offset = 0.041 trailing_only_offset_is_reached = True # --- Hyperoptable Entry Parameters (buy space) --- # These are defined directly in the class body. # The 'space' argument assigns them to the 'buy' hyperopt space. ema_fast_period = IntParameter(10, 60, default=19, space="buy", optimize=True) ema_slow_period = IntParameter(100, 250, default=175, space="buy", optimize=True) atr_period = IntParameter(5, 20, default=11, space="buy", optimize=True) atr_multiplier = DecimalParameter(1.0, 5.0, default=1.0, decimals=1, space="buy", optimize=True) # --- Strategy Settings --- startup_candle_count: int = 250 order_types = { 'entry': 'market', 'exit': 'market', 'stoploss': 'market', 'stoploss_on_exchange': False, } order_time_in_force = {'entry': 'gtc', 'exit': 'gtc'} # --- Hyperopt Space for Exit Parameters --- def populate_exit_trend_space(self) -> List[any]: """ Defines the hyperopt space for parameters used in exit logic. These are defined here because they are validated by Freqtrade at startup. """ return [ DecimalParameter(0.05, 0.25, default=0.15, name='stoploss'), IntParameter(10, 240, name='roi_t1'), DecimalParameter(0.01, 0.10, name='roi_p1'), CategoricalParameter([True, False], default=True, name='trailing_stop'), DecimalParameter(0.01, 0.10, default=0.03, name='trailing_stop_positive_offset'), DecimalParameter(0.005, 0.05, default=0.01, name='trailing_stop_positive'), CategoricalParameter([True, False], default=True, name='trailing_only_offset_is_reached'), ] # --- Indicator & Signal Logic --- def informative_pairs(self): return [] def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame: # MACD macd = ta.MACD(dataframe) dataframe['macd'] = macd['macd'] dataframe['macdsignal'] = macd['macdsignal'] # EMAs - uses the value from the hyperoptable parameter dataframe['ema_fast'] = ta.EMA(dataframe, timeperiod=self.ema_fast_period.value) dataframe['ema_slow'] = ta.EMA(dataframe, timeperiod=self.ema_slow_period.value) # ATR - uses the value from the hyperoptable parameter dataframe['atr'] = ta.ATR(dataframe, timeperiod=self.atr_period.value) return dataframe def populate_entry_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: dataframe.loc[ ( (dataframe['ema_fast'] > dataframe['ema_slow']) & (qtpylib.crossed_above(dataframe['macd'], dataframe['macdsignal'])) ), 'enter_long'] = 1 dataframe.loc[ ( (dataframe['ema_fast'] < dataframe['ema_slow']) & (qtpylib.crossed_below(dataframe['macd'], dataframe['macdsignal'])) ), 'enter_short'] = 1 return dataframe def populate_exit_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: # Exits are primarily handled by ROI, Stoploss, and Trailing Stop return dataframe def custom_stoploss(self, pair: str, trade: Trade, current_time: datetime, current_rate: float, current_profit: float, **kwargs) -> float: dataframe, _ = self.dp.get_analyzed_dataframe(pair, self.timeframe) last_candle = dataframe.iloc[-1].squeeze() if last_candle is not None and 'atr' in last_candle and last_candle['atr'] > 0: return (last_candle['atr'] * self.atr_multiplier.value) / current_rate # Fallback to the stoploss defined in the exit space or static default return self.stoploss def leverage(self, **kwargs) -> float: return 3.0 |
Strategy League — fixed backtest that feeds the ranking
Export report Freqtrade logsRun finished · took 63.1s
ℹ️ This strategy uses a trailing stop / custom_stoploss() — freqtrade only
re-checks these once per 4h candle by default, not against the price movement within it.
For a more accurate read, re-run this backtest locally with --timeframe-detail 1m
(or 5m — freqtrade's own docs use 5m detail for an hourly strategy as a lighter
alternative). Freqle doesn't do this for every check here: multiplying every
League/sweep backtest by a finer detail timeframe is more compute than the sandbox can sustain
across every indexed strategy. why this matters →
- statistically significant edge (p=0.00)
- 100% of resampled runs stayed profitable
- profitable across 85% of rolling 3-month windows
- comfortably beat buy-and-hold
Resampling the trade sequence 2,000× shows the spread of results this edge could plausibly produce — separating a dependable strategy from one that got lucky once.
Loading charts…
Monthly breakdown
| Month | Regime | Trades | Profit % | Avg % | Win | Loss | Win % | DD % | Avg dur |
|---|---|---|---|---|---|---|---|---|---|
| Jan 2026 | bullish trending low vol | 6 | -3.51 | -6.03 | 0 | 6 | 0.0 | -1.2 | 132h 00m |
| Dec 2025 | bearish trending low vol | 169 | +24.55 | 1.47 | 141 | 28 | 83.4 | -1.45 | 21h 45m |
| Nov 2025 | bearish trending high vol | 150 | +51.47 | 3.48 | 129 | 21 | 86.0 | -0.74 | 11h 22m |
| Oct 2025 | bearish trending low vol | 147 | +65.08 | 4.42 | 112 | 35 | 76.2 | -4.79 | 26h 30m |
| Sep 2025 | bullish choppy low vol | 100 | -5.00 | -0.47 | 80 | 20 | 80.0 | -3.86 | 44h 24m |
| Aug 2025 | bearish choppy low vol | 139 | -26.15 | -1.89 | 102 | 37 | 73.4 | -3.51 | 23h 08m |
| Jul 2025 | bullish choppy low vol | 149 | +51.77 | 3.52 | 134 | 15 | 89.9 | -1.25 | 20h 31m |
| Jun 2025 | bearish choppy low vol | 129 | +42.51 | 3.33 | 110 | 19 | 85.3 | -4.02 | 16h 15m |
| May 2025 | bullish trending low vol | 112 | -31.78 | -2.88 | 80 | 32 | 71.4 | -4.02 | 40h 09m |
| Apr 2025 | bullish choppy low vol | 145 | +30.15 | 2.13 | 122 | 23 | 84.1 | -1.78 | 15h 10m |
| Mar 2025 | bearish trending high vol | 130 | -3.58 | -0.26 | 102 | 28 | 78.5 | -2.09 | 26h 04m |
| Feb 2025 | bearish trending low vol | 150 | +57.59 | 3.87 | 130 | 20 | 86.7 | -0.96 | 16h 38m |
| Jan 2025 | bearish choppy low vol | 158 | +27.77 | 1.75 | 119 | 39 | 75.3 | -2.31 | 15h 55m |
| Dec 2024 | bullish trending low vol | 174 | +15.91 | 0.92 | 132 | 42 | 75.9 | -2.93 | 11h 20m |
| Nov 2024 | bullish trending low vol | 165 | +55.28 | 3.36 | 132 | 33 | 80.0 | -5.17 | 12h 47m |
| Oct 2024 | bullish choppy low vol | 117 | -11.10 | -0.95 | 91 | 26 | 77.8 | -6.11 | 31h 54m |
| Sep 2024 | bearish choppy low vol | 148 | +15.60 | 1.07 | 120 | 28 | 81.1 | -5.94 | 28h 21m |
| Aug 2024 | bearish choppy high vol | 103 | -13.03 | -1.28 | 78 | 25 | 75.7 | -6.01 | 24h 54m |
| Jul 2024 | bearish trending low vol | 128 | -41.56 | -3.25 | 89 | 39 | 69.5 | -5.12 | 34h 09m |
| Jun 2024 | bearish choppy low vol | 166 | +52.21 | 3.15 | 143 | 23 | 86.1 | -1.97 | 30h 09m |
| May 2024 | bullish choppy high vol | 136 | +13.49 | 0.97 | 112 | 24 | 82.4 | -2.27 | 26h 14m |
| Apr 2024 | bearish choppy high vol | 143 | +5.03 | 0.32 | 110 | 33 | 76.9 | -5.83 | 18h 33m |
| Mar 2024 | bullish trending high vol | 206 | +11.14 | 0.53 | 150 | 56 | 72.8 | -3.84 | 11h 55m |
| Feb 2024 | bullish trending low vol | 164 | +26.92 | 1.65 | 136 | 28 | 82.9 | -1.55 | 26h 51m |
| Jan 2024 | bearish choppy high vol | 175 | +11.63 | 0.65 | 140 | 35 | 80.0 | -4.04 | 15h 45m |
| Dec 2023 | bullish trending low vol | 188 | +54.86 | 2.94 | 157 | 31 | 83.5 | -1.08 | 18h 31m |
| Nov 2023 | bullish trending low vol | 191 | +66.92 | 3.52 | 167 | 24 | 87.4 | -1.25 | 16h 31m |
| Oct 2023 | bullish trending low vol | 126 | +32.20 | 2.57 | 107 | 19 | 84.9 | -2.12 | 35h 09m |
| Sep 2023 | bearish choppy low vol | 89 | +31.46 | 3.55 | 79 | 10 | 88.8 | -0.61 | 37h 21m |
| Aug 2023 | bearish choppy low vol | 117 | +12.82 | 1.09 | 90 | 27 | 76.9 | -1.41 | 48h 37m |
| Jul 2023 | bullish trending low vol | 119 | +35.59 | 3.00 | 97 | 22 | 81.5 | -1.46 | 31h 06m |
| Jun 2023 | bullish trending low vol | 158 | +51.72 | 3.27 | 128 | 30 | 81.0 | -3.23 | 17h 57m |
| May 2023 | bearish choppy low vol | 134 | +46.09 | 3.46 | 121 | 13 | 90.3 | -7.36 | 32h 38m |
| Apr 2023 | bullish trending low vol | 102 | -24.54 | -2.43 | 70 | 32 | 68.6 | -8.11 | 45h 27m |
| Mar 2023 | bullish trending high vol | 163 | -10.67 | -0.64 | 121 | 42 | 74.2 | -4.07 | 26h 39m |
| Feb 2023 | bullish trending low vol | 129 | +10.47 | 0.82 | 103 | 26 | 79.8 | -2.84 | 20h 24m |
| Jan 2023 | bullish trending low vol | 169 | +26.55 | 1.57 | 134 | 35 | 79.3 | -4.45 | 22h 42m |
| Dec 2022 | bearish trending low vol | 119 | +12.69 | 1.07 | 95 | 24 | 79.8 | -2.33 | 45h 55m |
| Nov 2022 | bearish trending high vol | 136 | +49.41 | 3.65 | 115 | 21 | 84.6 | -8.34 | 19h 19m |
| Oct 2022 | bullish choppy low vol | 130 | +5.11 | 0.40 | 106 | 24 | 81.5 | -8.91 | 27h 21m |
| Sep 2022 | bearish choppy high vol | 134 | +0.63 | 0.06 | 107 | 27 | 79.9 | -11.9 | 21h 31m |
| Aug 2022 | bullish choppy high vol | 124 | +15.09 | 1.23 | 100 | 24 | 80.6 | -11.76 | 16h 29m |
| Jul 2022 | bullish trending high vol | 86 | -23.25 | -2.72 | 60 | 26 | 69.8 | -13.0 | 16h 22m |
| Jun 2022 | bearish trending high vol | 133 | -3.54 | -0.26 | 101 | 32 | 75.9 | -8.82 | 13h 57m |
| May 2022 | bearish trending high vol | 107 | +40.81 | 3.86 | 82 | 25 | 76.6 | -6.04 | 9h 32m |
| Apr 2022 | bearish choppy high vol | 159 | +15.77 | 1.05 | 127 | 32 | 79.9 | -13.25 | 16h 03m |
| Mar 2022 | bullish choppy high vol | 156 | -23.70 | -1.50 | 115 | 41 | 73.7 | -10.58 | 21h 02m |
| Feb 2022 | bearish trending high vol | 147 | -9.91 | -0.71 | 100 | 47 | 68.0 | -6.3 | 13h 18m |
| Jan 2022 | bearish trending high vol | 140 | +24.70 | 1.78 | 111 | 29 | 79.3 | -5.97 | 15h 10m |
| Dec 2021 | bearish trending high vol | 161 | +18.99 | 1.22 | 134 | 27 | 83.2 | -5.25 | 12h 48m |
| Nov 2021 | bearish trending high vol | 155 | +35.91 | 2.35 | 131 | 24 | 84.5 | -2.44 | 15h 26m |
| Oct 2021 | bullish trending high vol | 129 | +21.08 | 1.67 | 107 | 22 | 82.9 | -2.82 | 18h 59m |
| Sep 2021 | bearish trending high vol | 135 | +17.41 | 1.21 | 107 | 28 | 79.3 | -4.5 | 16h 00m |
| Aug 2021 | bullish trending high vol | 174 | +30.14 | 1.69 | 142 | 32 | 81.6 | -8.12 | 14h 08m |
| Jul 2021 | bullish trending high vol | 185 | +20.86 | 1.15 | 147 | 38 | 79.5 | -7.85 | 12h 52m |
| Jun 2021 | bearish trending high vol | 146 | +29.09 | 2.02 | 112 | 34 | 76.7 | -5.84 | 4h 48m |
| May 2021 | bearish trending high vol | 183 | +59.00 | 3.24 | 142 | 41 | 77.6 | -5.79 | 4h 04m |
| Apr 2021 | bearish choppy high vol | 155 | +58.59 | 3.80 | 127 | 28 | 81.9 | -6.28 | 9h 33m |
| Mar 2021 | bullish choppy high vol | 132 | +33.83 | 2.61 | 108 | 24 | 81.8 | -7.68 | 11h 42m |
| Feb 2021 | bullish trending high vol | 165 | +72.25 | 4.45 | 129 | 36 | 78.2 | -6.31 | 5h 52m |
| Jan 2021 | bullish trending high vol | 162 | +39.55 | 2.46 | 129 | 33 | 79.6 | -9.23 | 4h 22m |
Yearly breakdown
| Year | Trades | Profit % | Avg % | Win | Loss | Win % | DD % | Avg dur |
|---|---|---|---|---|---|---|---|---|
| 2026 | 6 | -3.51 | -6.03 | 0 | 6 | 0.0 | -1.2 | 132h 00m |
| 2025 | 1678 | +284.38 | 1.71 | 1361 | 317 | 81.1 | -4.79 | 22h 09m |
| 2024 | 1825 | +141.52 | 0.77 | 1433 | 392 | 78.5 | -6.11 | 21h 48m |
| 2023 | 1685 | +333.47 | 1.99 | 1374 | 311 | 81.5 | -8.11 | 27h 33m |
| 2022 | 1571 | +103.81 | 0.67 | 1219 | 352 | 77.6 | -13.25 | 19h 35m |
| 2021 | 1882 | +436.70 | 2.34 | 1515 | 367 | 80.5 | -9.23 | 10h 39m |
Trade charts — best 2 and worst 2 performing pairs (full OHLC candles are expensive to render for every pair)
Backtests — over a market period
Backtest this strategy over a chosen crypto-cycle period. These don't affect the League ranking, and need that period's candle data downloaded.
Log in or sign up to run backtests.
| Period | Range | Total % | Win % | Max DD | Trades | |
|---|---|---|---|---|---|---|
| 2020 · DeFi Summer & Pre-Halving Rally | 20200101-20210101 | not run | ||||
| 2021 · Institutional Bull Market | 20210101-20220101 | not run | ||||
| 2022 · Post-Bull Crash & Macro Tightening | 20220101-20230101 | not run | ||||
| 2023–2024 · Recovery & ETF Anticipation | 20230101-20250101 | not run | ||||
| 2025–2026 · Current Cycle | 20250101-20260101 | not run | ||||
Walk forward
Out-of-sample backtest on recent data · 33 pairs · 20260101-20260701.
Backtest trust check
no lookahead patterns · 1 thing(s) worth reviewing before trusting the numbers
| Line | Pattern | Detail | |
|---|---|---|---|
| 118 | review | dead_callback | custom_stoploss() is defined but use_custom_stoploss isn't True, and freqtrade only calls it when that flag is set -- the method never runs and every trade uses the static stoploss |
ran by Ron · took s
Lookahead analysis
Freqtrade logsno lookahead bias detected
20 signal(s) analysed · 0 biased entries · 0 biased exits
ran by Ron · took 21.6s