Basics
mode: spot
timeframe: 1h
interface version: 3
Settings
stoploss: -1.0
has minimal roi
hyperopt
hyperopt params: 4
Indicators
CMF
EMA
MFI
talib
technical
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 | """ this strat entry deep and exit up and it's not smart sorry u or gain profit or just hodl(when drawdown) i fixed some of false signal, thank EMA(200) when long drawdown, some time u get only exit_profit_offset! Because get false exit signal bellow entry price. but u have no stop-loss and exit only profit Do Backtesting first freqtrade backtesting -s SmartMoneyStrategy --timerange 20210601- -i 1h -p DOT/USDT Lets plot: freqtrade plot-dataframe -s SmartMoneyStrategy --timerange 20210601- -i 1h -p DOT/USDT --indicators1 ema_200 --indicators2 cmf mfi Params hyper-optable, just use class SmartMoneyStrategyHyperopt freqtrade hyperopt --hyperopt-loss SharpeHyperOptLoss --strategy SmartMoneyStrategyHyperopt --spaces entry exit --timerange 20210601- --dry-run-wallet 160 --stake 12 -i 1h -e 1000 """ import numpy import talib.abstract as ta from pandas import DataFrame from technical.indicators import chaikin_money_flow from freqtrade.strategy import DecimalParameter, IStrategy, IntParameter class SmartMoneyStrategy(IStrategy): INTERFACE_VERSION = 3 # Minimal ROI designed for the strategy. minimal_roi = {'0': 10} # Stoploss: stoploss = -1 # Optimal timeframe for the strategy timeframe = '30m' exit_profit_only = True exit_profit_offset = 0.01 # enumeration of indicators def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame: # Chaikin dataframe['cmf'] = chaikin_money_flow(dataframe, period=20) # MFI dataframe['mfi'] = ta.MFI(dataframe) # EMA dataframe['ema_200'] = ta.EMA(dataframe, timeperiod=200) return dataframe # params for entry def populate_entry_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: dataframe.loc[(dataframe['close'] < dataframe['ema_200']) & (dataframe['mfi'] < 35) & (dataframe['cmf'] < -0.07), 'enter_long'] = 1 return dataframe # params for exit def populate_exit_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: dataframe.loc[(dataframe['close'] > dataframe['ema_200']) & (dataframe['mfi'] > 70) & (dataframe['cmf'] > 0.2), 'exit_long'] = 1 # dataframe.to_csv('./exit_result.csv') return dataframe # FOR HYPEROPT class SmartMoneyStrategyHyperopt(IStrategy): INTERFACE_VERSION = 3 # ROI table: minimal_roi = {'0': 10} # Stoploss: stoploss = -1 # Optimal timeframe for the strategy timeframe = '1h' exit_profit_only = True exit_profit_offset = 0.01 # entry params entry_mfi = IntParameter(20, 60, default=35, space='entry') entry_cmf = DecimalParameter(-0.4, -0.01, decimals=2, default=-0.07, space='entry') # exit params exit_mfi = IntParameter(50, 95, default=70, space='exit') exit_cmf = DecimalParameter(0.1, 0.6, decimals=2, default=0.2, space='exit') def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame: # Chaikin dataframe['cmf'] = chaikin_money_flow(dataframe, period=20) # MFI dataframe['mfi'] = ta.MFI(dataframe) # EMA dataframe['ema_200'] = ta.EMA(dataframe, timeperiod=200) return dataframe def populate_entry_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: dataframe.loc[(dataframe['close'] < dataframe['ema_200']) & (dataframe['mfi'] < self.entry_mfi.value) & (dataframe['cmf'] < self.entry_cmf.value), 'enter_long'] = 1 return dataframe def populate_exit_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: dataframe.loc[(dataframe['close'] > dataframe['ema_200']) & (dataframe['mfi'] > self.exit_mfi.value) & (dataframe['cmf'] > self.exit_cmf.value), 'exit_long'] = 1 return dataframe |
Strategy League — fixed backtest that feeds the ranking
Export report Freqtrade logsRun finished · took 56.6s
pairs 33 pairs
timerange 20210101-20260101
mode spot
timeframe 1h
stake 100 USDT
wallet 1000 USDT
max open trades 10
fee exchange lowest tier
total profit+32.83%
final wallet1328 USDT
win rate92.1%
max drawdown-39.33%
market change+447.62%
vs market-414.79%
timeframe1h
profit factor1.38
expectancy ratio0.03
break-even fee1.3997%
sharpe0.125
sortino0.411
CAGR+5.8%
calmar0.873
avg MFE+14.22%
avg MAE-21.03%
avg profit/trade2.6%
avg duration3420h 03m
best trade+48.87%
worst trade-99.12%
win/loss streak116 / 10
positive months13/14
consistent (3-mo)91.7%
worst 3-mo-82.74%
trades126
revision1
likely annual return+6%
range (5th–95th)-1% … +12%
chance of profit92.8%
worst-5% outcome-2%
significance (p)0.1544
risk of ruin0.0%
- profit isn't statistically significant (p=0.15) — hard to tell apart from luck
- did not beat simply holding the market
- 93% of resampled runs stayed profitable
- profitable across 92% of rolling 3-month windows
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 | 10 | -86.12 | -86.25 | 0 | 10 | 0.0 | -39.33 | 30833h 30m |
| Jan 2025 | bearish choppy low vol | 1 | +0.29 | 2.93 | 1 | 0 | 100.0 | 0.0 | 1001h 00m |
| Dec 2024 | bullish trending low vol | 4 | +3.09 | 7.75 | 4 | 0 | 100.0 | 0.0 | 8404h 00m |
| Nov 2024 | bullish trending low vol | 2 | +0.41 | 2.03 | 2 | 0 | 100.0 | 0.0 | 15551h 30m |
| Mar 2024 | bullish trending high vol | 1 | +0.20 | 2.02 | 1 | 0 | 100.0 | 0.0 | 327h 00m |
| Feb 2024 | bullish trending low vol | 3 | +0.72 | 2.39 | 3 | 0 | 100.0 | 0.0 | 8157h 40m |
| Nov 2021 | bullish trending high vol | 3 | +1.99 | 6.64 | 3 | 0 | 100.0 | 0.0 | 154h 20m |
| Oct 2021 | bullish trending high vol | 3 | +0.83 | 2.76 | 3 | 0 | 100.0 | 0.0 | 1513h 40m |
| Sep 2021 | bearish trending high vol | 2 | +0.44 | 2.19 | 2 | 0 | 100.0 | 0.0 | 3494h 00m |
| May 2021 | bearish trending high vol | 10 | +4.30 | 4.30 | 10 | 0 | 100.0 | 0.0 | 319h 12m |
| Apr 2021 | bearish choppy high vol | 27 | +28.63 | 10.61 | 27 | 0 | 100.0 | 0.0 | 282h 49m |
| Mar 2021 | bullish choppy high vol | 14 | +10.88 | 7.77 | 14 | 0 | 100.0 | 0.0 | 229h 34m |
| Feb 2021 | bullish trending high vol | 23 | +35.16 | 15.30 | 23 | 0 | 100.0 | 0.0 | 140h 21m |
| Jan 2021 | bullish trending high vol | 23 | +32.00 | 13.91 | 23 | 0 | 100.0 | 0.0 | 122h 08m |
Yearly breakdown
| Year | Trades | Profit % | Avg % | Win | Loss | Win % | DD % | Avg dur |
|---|---|---|---|---|---|---|---|---|
| 2026 | 10 | -86.12 | -86.25 | 0 | 10 | 0.0 | -39.33 | 30833h 30m |
| 2025 | 1 | +0.29 | 2.93 | 1 | 0 | 100.0 | 0.0 | 1001h 00m |
| 2024 | 10 | +4.42 | 4.43 | 10 | 0 | 100.0 | 0.0 | 8951h 54m |
| 2021 | 105 | +114.23 | 10.88 | 105 | 0 | 100.0 | 0.0 | 305h 26m |
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 | |
|---|---|---|---|
| 23 | review | missing_startup_candles | uses recursive indicators (EMA) 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=200) needing 3x warmup, so it needs at least that many. Set it to a few times the longest period and confirm with `freqtrade recursive-analysis` |
ran by Ron · took s
Lookahead analysis
freqtrade lookahead-analysis: detects strategies peeking at future candles.