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 | from freqtrade.strategy import IStrategy from pandas import DataFrame from datetime import datetime import numpy as np import talib.abstract as ta import freqtrade.vendor.qtpylib.indicators as qtpylib class CombinedStrategy(IStrategy): INTERFACE_VERSION = 3 # Configurações gerais can_short = True timeframe = '5m' # Timeframe principal informative_timeframe = '5m' # Timeframe informativo adicional stoploss = -0.25 trailing_stop = True trailing_stop_positive = 0.01 trailing_stop_positive_offset = 0.02 minimal_roi = { "0": 0.05, "20": 0.04, "30": 0.03, "60": 0.01 } def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame: """ Popula os indicadores necessários para a estratégia. """ # Certifique-se de que o dataframe não está vazio if dataframe.empty: return dataframe # RSI (Índice de Força Relativa) dataframe['rsi'] = ta.RSI(dataframe, timeperiod=14) # MACD (Moving Average Convergence Divergence) macd = ta.MACD(dataframe, fastperiod=12, slowperiod=26, signalperiod=9) dataframe['macd'] = macd['macd'] dataframe['macdsignal'] = macd['macdsignal'] # ADX (Average Directional Index) dataframe['adx'] = ta.ADX(dataframe, timeperiod=14) # Médias Móveis Exponenciais (EMA) dataframe['ema20'] = ta.EMA(dataframe, timeperiod=20) dataframe['ema50'] = ta.EMA(dataframe, timeperiod=50) # Gradiente do RSI (Gradiente da EMA do RSI) rsi_ema = ta.EMA(dataframe['rsi'], timeperiod=14) dataframe['rsi_gra'] = np.gradient(rsi_ema) return dataframe def populate_entry_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: """ Define as condições de entrada para long e short. """ # Certifique-se de que o dataframe não está vazio if dataframe.empty: return dataframe # Entrada long (compra) dataframe.loc[ ( (dataframe['rsi'] > 50) & # RSI acima de 50 (dataframe['macd'] > dataframe['macdsignal']) & # MACD cruzando para cima (dataframe['adx'] > 25) & # ADX indicando tendência forte (dataframe['rsi_gra'] > 0) # Gradiente positivo do RSI ), 'enter_long'] = 1 # Entrada short (venda) dataframe.loc[ ( (dataframe['rsi'] < 50) & # RSI abaixo de 50 (dataframe['macd'] < dataframe['macdsignal']) & # MACD cruzando para baixo (dataframe['adx'] > 25) & # ADX indicando tendência forte (dataframe['rsi_gra'] < 0) # Gradiente negativo do RSI ), 'enter_short'] = 1 return dataframe def populate_exit_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: """ Define as condições de saída para long e short. """ # Certifique-se de que o dataframe não está vazio if dataframe.empty: return dataframe # Saída long dataframe.loc[ ( (dataframe['rsi'] > 70) | # RSI em sobrecompra qtpylib.crossed_below(dataframe['ema20'], dataframe['ema50']) # EMA20 cruzando abaixo da EMA50 ), 'exit_long'] = 1 # Saída short dataframe.loc[ ( (dataframe['rsi'] < 30) | # RSI em sobrevenda qtpylib.crossed_above(dataframe['ema20'], dataframe['ema50']) # EMA20 cruzando acima da EMA50 ), 'exit_short'] = 1 return dataframe def custom_stoploss(self, pair: str, trade: 'Trade', current_time: datetime, current_rate: float, current_profit: float, **kwargs) -> float: """ Stop-loss dinâmico baseado no lucro atual. """ if current_profit > 0.3: return 0.01 elif current_profit > 0.1: return 0.02 elif current_profit > 0.05: return 0.05 return 0.1 |
Strategy League — fixed backtest that feeds the ranking
Export report Freqtrade logsRun finished · took 537.0s
ℹ️ This strategy uses a trailing stop / custom_stoploss() — freqtrade only
re-checks these once per 5m candle by default, not against the price movement within it.
For a more accurate read, re-run this backtest locally with --timeframe-detail 1m. 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 →
- profit isn't statistically significant (p=1.00) — hard to tell apart from luck
- only 0% of resampled runs were profitable
- profitable in only 0% of rolling 3-month windows
- did not beat simply holding the market
- very deep drawdown (-90%)
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 |
|---|---|---|---|---|---|---|---|---|---|
| Aug 2021 | bullish trending high vol | 264 | -4.57 | -0.17 | 142 | 122 | 53.8 | -90.45 | 2h 27m |
| Jul 2021 | bullish trending high vol | 311 | -2.53 | -0.09 | 163 | 148 | 52.4 | -86.32 | 2h 22m |
| Jun 2021 | bearish trending high vol | 488 | -4.74 | -0.10 | 291 | 197 | 59.6 | -84.13 | 1h 53m |
| May 2021 | bearish trending high vol | 1116 | -7.16 | -0.05 | 640 | 476 | 57.3 | -81.64 | 1h 19m |
| Apr 2021 | bearish choppy high vol | 1133 | -16.39 | -0.15 | 704 | 429 | 62.1 | -72.61 | 2h 04m |
| Mar 2021 | bullish choppy high vol | 1684 | -31.24 | -0.19 | 964 | 720 | 57.2 | -57.07 | 2h 27m |
| Feb 2021 | bullish trending high vol | 2411 | -12.94 | -0.06 | 1553 | 858 | 64.4 | -48.96 | 1h 47m |
| Jan 2021 | bullish trending high vol | 3553 | -10.33 | -0.03 | 2297 | 1256 | 64.6 | -21.67 | 1h 46m |
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
1 potential lookahead pattern(s) found · 2 to review
| Line | Pattern | Detail | |
|---|---|---|---|
| 53 | leak | noncausal_transform | 'gradient' is non-causal -- central difference -- reads a[i+1] as well as a[i-1]. The value at every bar already contains the next one, so anything derived from it knows the future. For a causal slope use .diff() (backward difference) instead |
| 8 | review | missing_startup_candles | uses recursive indicators (ADX, EMA, MACD, RSI) but startup_candle_count is not set (default 0). Their value at a bar depends on all bars before it, so freqtrade trims no warmup and the backtest opens with unwarmed values that can't occur live. The longest lookback visible here is EMA(timeperiod=50), so it needs at least that many. Set it to a few times the longest period and confirm with `freqtrade recursive-analysis` |
| 113 | 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 lookahead-analysis: detects strategies peeking at future candles.