Add Regime Detection to Your Freqtrade Bot
Freqtrade is the most popular open-source crypto trading bot. But most Freqtrade strategies have one critical weakness: they trade the same way in every market condition.
A momentum strategy that profits in a bull market hemorrhages during chop. A mean reversion strategy that works in ranging markets gets steamrolled by trends.
The fix: add regime detection to your Freqtrade strategy so it knows what kind of market it's in.
The Freqtrade Endpoint
Regime has a dedicated Freqtrade-optimized endpoint:
curl https://getregime.com/api/v1/freqtrade/regime
Response:
{
"regime": "bear",
"confidence": 0.71,
"action": "reduce_exposure",
"signalSummary": { "bullish": 1, "bearish": 3, "neutral": 2 }
}
The action field maps directly to Freqtrade behavior:
-
"full_trading"→ Normal operation (bull regime) -
"reduce_exposure"→ Reduce position sizes (bear regime) -
"minimal_trading"→ Skip most entries (chop regime)
Integration: Custom Strategy
Add this to your Freqtrade strategy class:
import requests
from freqtrade.strategy import IStrategy
class RegimeAwareStrategy(IStrategy):
# Cache regime for 5 minutes to avoid excessive API calls
_regime_cache = None
_regime_cache_ts = 0
def get_regime(self):
import time
now = time.time()
if self._regime_cache and now - self._regime_cache_ts < 300:
return self._regime_cache
try:
resp = requests.get(
"https://getregime.com/api/v1/freqtrade/regime",
timeout=10
)
self._regime_cache = resp.json()
self._regime_cache_ts = now
except:
self._regime_cache = {"regime": "chop", "confidence": 0.5, "action": "minimal_trading"}
return self._regime_cache
def custom_stake_amount(self, pair, current_time, current_rate,
proposed_stake, min_stake, max_stake, **kwargs):
"""Scale position size by regime."""
regime = self.get_regime()
scale = {
"bull": 1.0,
"chop": 0.4,
"bear": 0.15,
}.get(regime["regime"], 0.5)
# Further scale by confidence
if regime["confidence"] < 0.6:
scale *= regime["confidence"] / 0.6
return proposed_stake * scale
def confirm_trade_entry(self, pair, order_type, amount, rate, time_in_force,
current_time, entry_tag, side, **kwargs):
"""Block entries in strong bear regimes."""
regime = self.get_regime()
if regime["regime"] == "bear" and regime["confidence"] > 0.8:
return False # Don't enter in strong bear
return True
Method 2: Regime as an Informative Pair
If you prefer a non-code approach, add regime as an informative pair:
def informative_pairs(self):
return [] # Regime API handles this externally
def populate_indicators(self, dataframe, metadata):
# Fetch regime once per candle evaluation
regime = self.get_regime()
dataframe["regime"] = regime["regime"]
dataframe["regime_confidence"] = regime["confidence"]
return dataframe
def populate_entry_trend(self, dataframe, metadata):
dataframe.loc[
(dataframe["regime"] != "bear") &
# ... your existing entry conditions ...
(dataframe["volume"] > 0),
"enter_long"
] = 1
return dataframe
What This Does to Returns
From backtesting 302K candles with SMA 50/200 crossover:
| Config | ETH Return | Max Drawdown |
|---|---|---|
| No regime filter | +41% | -52% |
| With regime filter | +166% | -31% |
| Bear block only | +89% | -38% |
The regime filter's biggest value is drawdown avoidance. It keeps you out of the worst periods.
Full Setup Guide
Detailed Freqtrade integration docs: getregime.com/freqtrade
The free API tier (no auth needed) is enough for most Freqtrade setups since strategies typically evaluate every 5 minutes — well within the 10 RPM free limit.
For real-time regime data and webhook alerts on regime shifts, upgrade to Pro ($49/mo).
Try Regime Intelligence
Regime is a real-time crypto market regime detection API. One endpoint tells you if the market is bull, bear, or chop — so your bot only trades when conditions match your strategy.
Top comments (0)