TechnicalExampleStrategy
Tested 1 Jun 2023 – 30 May 2025
Rank 24 of 27 by return
TechnicalExampleStrategy turned $1,000 into $201 (−80.0%) 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 80.0%, deep enough that most people would have switched it off. With a 26% win rate and a profit factor of 0.27, losses outweighed gains.
How TechnicalExampleStrategy trades
A single-indicator example from the technical library. It buys whenever Chaikin Money Flow is negative and sells when it turns positive, with a 1% take-profit and a 5% stoploss.
Included as a baseline. It shows how a one-line rule performs under exactly the same test conditions as the more elaborate strategies.
Rules at a glance
- Indicators
- Chaikin Money Flow 21
- Take-profit (minimal ROI)
- 1% from entry
- Stoploss
- −5%
- Trailing stop
- Off
- Exit signal
- Used
Results by month
Profit or loss in USDT for trades closed in each month.
Results by coin
| Pair | Trades | Win rate | Profit (USDT) | Avg. hold |
|---|---|---|---|---|
| DOGE/USDT | 134 | 18.7% | −46.62 | 41m |
| LINK/USDT | 116 | 20.7% | −51.18 | 52m |
| AVAX/USDT | 131 | 30.5% | −51.70 | 45m |
| XRP/USDT | 166 | 33.1% | −57.81 | 53m |
| DOT/USDT | 133 | 24.1% | −73.20 | 52m |
| BTC/USDT | 257 | 18.7% | −83.47 | 44m |
| BNB/USDT | 192 | 26.6% | −87.21 | 49m |
| ETH/USDT | 229 | 18.3% | −89.23 | 49m |
| SOL/USDT | 277 | 34.7% | −123.70 | 49m |
| ADA/USDT | 209 | 31.6% | −135.34 | 1h 3m |
Why trades closed
| Exit reason | Trades | Win rate | Profit (USDT) |
|---|---|---|---|
| Take-profit (ROI) | 58 | 100.0% | +116.05 |
| Stoploss | 17 | 0.0% | −175.85 |
| Exit signal | 1769 | 23.8% | −739.67 |
The code
TechnicalExampleStrategy comes from the community freqtrade-strategies repository (GPL-3.0). These are the parts that decide when it trades; the full file is 41 lines.
Entry rules
def populate_entry_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: dataframe.loc[ ( ( (dataframe['cmf'] < 0) ) ), 'enter_long'] = 1 return dataframe
Exit rules
def populate_exit_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: # different strategy used for sell points, due to be able to duplicate it to 100% dataframe.loc[ ( (dataframe['cmf'] > 0) ), 'exit_long'] = 1 return dataframe
Indicators
def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame: dataframe['cmf'] = cmf(dataframe, 21) 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 5m --timerange 20230501-20250530
freqtrade backtesting --strategy TechnicalExampleStrategy --timeframe 5m \
--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.