Strategy002
Tested 1 Jun 2023 – 30 May 2025
Rank 17 of 27 by return
Strategy002 turned $1,000 into $741 (−25.9%) over 729 days, while holding Bitcoin returned +288.1% and an equal mix of the ten coins +194.8%. Its worst drawdown was 35.8%, a substantial dip to sit through. It won 91% of its trades yet still lost money, because its few losing trades were much larger than its many small wins.
How Strategy002 trades
Strategy002 buys an oversold hammer candle: RSI under 30, slow stochastic under 20 and price below the lower Bollinger Band. It exits when the Parabolic SAR flips above price and the Fisher-transformed RSI is above 0.3.
Requiring a hammer pattern on top of three oversold readings makes entries rare. Few trades means results can swing a lot on a different time window.
Rules at a glance
- Indicators
- RSI, Stochastic, Bollinger Bands, Hammer candle, Parabolic SAR
- Take-profit (minimal ROI)
- 5% from entry; 4% after 20m; 3% after 30m; 1% after 1h 0m
- Stoploss
- −10%
- 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 |
|---|---|---|---|---|
| XRP/USDT | 52 | 94.2% | +15.34 | 23h 25m |
| DOT/USDT | 51 | 94.1% | +10.31 | 14h 6m |
| DOGE/USDT | 49 | 93.9% | +10.29 | 7h 1m |
| AVAX/USDT | 43 | 90.7% | −7.83 | 8h 29m |
| BTC/USDT | 43 | 93.0% | −30.06 | 23h 29m |
| LINK/USDT | 45 | 88.9% | −31.75 | 13h 50m |
| BNB/USDT | 43 | 90.7% | −44.29 | 1d 11h |
| SOL/USDT | 49 | 87.8% | −48.79 | 14h 8m |
| ETH/USDT | 39 | 87.2% | −53.57 | 20h 53m |
| ADA/USDT | 48 | 85.4% | −78.54 | 16h 22m |
Why trades closed
| Exit reason | Trades | Win rate | Profit (USDT) |
|---|---|---|---|
| Take-profit (ROI) | 207 | 100.0% | +495.42 |
| Exit signal | 212 | 100.0% | +112.96 |
| Still open at end of test | 1 | 0.0% | −11.99 |
| Stoploss | 42 | 0.0% | −855.27 |
The code
Strategy002 comes from the community freqtrade-strategies repository (GPL-3.0). These are the parts that decide when it trades; the full file is 136 lines.
Entry rules
def populate_entry_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: dataframe.loc[ ( (dataframe['rsi'] < 30) & (dataframe['slowk'] < 20) & (dataframe['bb_lowerband'] > dataframe['close']) & (dataframe['CDLHAMMER'] == 100) ), 'enter_long'] = 1 return dataframe
Exit rules
def populate_exit_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: dataframe.loc[ ( (dataframe['sar'] > dataframe['close']) & (dataframe['fisher_rsi'] > 0.3) ), 'exit_long'] = 1 return dataframe
Indicators
def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame: # Stoch stoch = ta.STOCH(dataframe) dataframe['slowk'] = stoch['slowk'] # RSI dataframe['rsi'] = ta.RSI(dataframe) # Inverse Fisher transform on RSI, values [-1.0, 1.0] (https://goo.gl/2JGGoy) rsi = 0.1 * (dataframe['rsi'] - 50) dataframe['fisher_rsi'] = (numpy.exp(2 * rsi) - 1) / (numpy.exp(2 * rsi) + 1) # Bollinger bands bollinger = qtpylib.bollinger_bands(qtpylib.typical_price(dataframe), window=20, stds=2) dataframe['bb_lowerband'] = bollinger['lower'] # SAR Parabol dataframe['sar'] = ta.SAR(dataframe) # Hammer: values [0, 100] dataframe['CDLHAMMER'] = ta.CDLHAMMER(dataframe) 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 Strategy002 --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.