RangeTrader
♡
Basics
mode: spot
timeframe: 1h
interface version: 3
Settings
stoploss: -0.15
trailing
Indicators
ADX
ATR
talib
Concepts
trailing
6 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 | from freqtrade.strategy import IStrategy from pandas import DataFrame import talib.abstract as ta import freqtrade.vendor.qtpylib.indicators as qtpylib import numpy # noqa class RangeTrader(IStrategy): INTERFACE_VERSION = 3 '\n RangeTrader\n author@: Pip Rumpelstiltskin\n\n How to use it?\n\n > freqtrade download-data --timeframes 1h --timerange=20200101-20250117\n > freqtrade backtesting --export trades -s RangeTrader --timeframe 1h --timerange=20200101-20250117\n > freqtrade plot-dataframe -s RangeTrader --indicators1 support resistance --timeframe 1h --timerange=20200101-20250117\n\n ' # Minimal ROI designed for the strategy. # This attribute will be overridden if the config file contains "minimal_roi" # minimal_roi = { # "40": 0.0, # "30": 0.01, # "20": 0.02, # "0": 0.04 # } # This attribute will be overridden if the config file contains "stoploss" stoploss = -0.15 # Keep losses tight, ain't got time for bleeding # Optimal timeframe for the strategy timeframe = '1h' # trailing stoploss trailing_stop = True def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame: """ Populate the indicators for support and resistance. We're marking the battlegrounds here, guv. Keep your eye on these lines! """ lookback_period = 20 # How far back we’re looking for levels # Volatility-based adjustment using ATR # ATR gives us a sense of the average range, handy for dynamic levels atr = ta.ATR(dataframe, timeperiod=14) dataframe['support'] = dataframe['low'].rolling(lookback_period).min() - atr dataframe['resistance'] = dataframe['high'].rolling(lookback_period).max() + atr dataframe['mid_point'] = (dataframe['support'] + dataframe['resistance']) / 2 # Detecting trend markets using ADX # If ADX is low, we assume a range-bound market dataframe['adx'] = ta.ADX(dataframe) dataframe['in_range_market'] = dataframe['adx'] < 25 # Only trade if ADX is low return dataframe def populate_entry_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: """ Buy when we're near the bottom of the range. Buy low, mate, sell high! Bob’s your uncle. """ # Close price near support (fading the dip) # Make sure there's some action in the market, no ghosts # Ensure we're in a range market dataframe.loc[(dataframe['close'] <= dataframe['support'] * 1.01) & (dataframe['volume'] > 0) & (dataframe['in_range_market'] == True), 'enter_long'] = 1 return dataframe def populate_exit_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: """ Sell when we’re near the top, or get out if the party’s over. Don’t let greed nick your profits! """ # Close price near resistance (taking profit at the top) # Or if price buggers off past support—don’t hang about # Ensure we're not in a trending market dataframe.loc[(dataframe['close'] >= dataframe['resistance'] * 0.99) | (dataframe['close'] < dataframe['support'] * 0.98) | (dataframe['in_range_market'] == False), 'exit_long'] = 1 # Implementing partial exit at the mid-point # This ensures we lock in some profits if the market reaches halfway dataframe.loc[(dataframe['close'] >= dataframe['mid_point']) & (dataframe['volume'] > 0), 'sell_partial'] = 0.5 # Sell half position near mid-point return dataframe |
Strategy League — fixed backtest that feeds the ranking
The fixed-params backtest (33 pairs · 20210101-20260101) — the only run that feeds the Strategy League ranking.
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
Static source analysis — instant, does not run the strategy. Flags future-data leaks, backtest-realism problems, and indicators worth a second look.
Lookahead analysis
freqtrade lookahead-analysis: detects strategies peeking at future candles.