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:

``bash

curl https://getregime.com/api/v1/freqtrade/regime

`

Response:

`json

{

"regime": "bear",

"confidence": 0.71,

"action": "reduce_exposure",

"signalSummary": { "bullish": 1, "bearish": 3, "neutral": 2 }

}

`

The action field maps directly to Freqtrade behavior:

Integration: Custom Strategy

Add this to your Freqtrade strategy class:

`python

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:

`python

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).