Crypto Regime Detection in Python: Complete Tutorial

Market regime detection is the difference between a profitable trading bot and one that bleeds money in the wrong conditions. In this tutorial, you'll learn how to detect crypto regimes in Python and use them to make better trading decisions.

What You'll Build

By the end of this tutorial, you'll have:

  • A regime-aware position sizing system
  • A regime shift alert system (email/Slack notifications)
  • A simple backtest framework comparing regime-filtered vs unfiltered returns
  • Setup

    pip install requests

    That's it. No complex dependencies.

    Step 1: Fetch the Current Regime

    import requests
    from datetime import datetime
    
    API_BASE = "https://getregime.com/api/v1"
    
    def get_regime():
        """Fetch current market regime classification."""
        resp = requests.get(f"{API_BASE}/market/regime", timeout=10)
        resp.raise_for_status()
        return resp.json()
    
    

    Test it

    regime = get_regime() print(f"Regime: {regime['regime'].upper()}") print(f"Confidence: {regime['confidence']:.0%}") print(f"Signals: {regime.get('signalSummary', {})}")

    Output:

    Regime: BEAR
    Confidence: 71%
    Signals: {'bullish': 1, 'bearish': 3, 'neutral': 2}

    The API returns one of three regimes:

    Step 2: Regime-Aware Position Sizing

    The simplest and most effective application — scale your position size based on the regime:

    REGIME_MULTIPLIERS = {
        "bull": 1.0,    # Full size
        "chop": 0.4,    # 40% — reduced edge
        "bear": 0.1,    # 10% — capital preservation
    }
    
    def calculate_position(capital, base_risk_pct=0.02):
        """Calculate position size adjusted for current regime."""
        regime = get_regime()
    
        base_size = capital * base_risk_pct
        regime_mult = REGIME_MULTIPLIERS.get(regime["regime"], 0.5)
    
        # Scale by confidence — uncertain regimes get smaller sizes
        conf = regime["confidence"]
        conf_mult = 1.0 if conf >= 0.6 else conf / 0.6
    
        final_size = base_size  regime_mult  conf_mult
    
        print(f"Regime: {regime['regime'].upper()} ({conf:.0%})")
        print(f"Base size: ${base_size:.2f}")
        print(f"Regime adjusted: ${final_size:.2f} ({regime_mult * conf_mult:.0%} of base)")
    
        return final_size
    
    

    With $10,000 capital

    position = calculate_position(10000)

    Step 3: Regime Shift Alerts

    Get notified when the market regime changes:

    import time
    import json
    
    def monitor_regime(check_interval=300, callback=None):
        """Monitor regime and alert on changes."""
        last_regime = None
    
        while True:
            try:
                data = get_regime()
                current = data["regime"]
    
                if last_regime is not None and current != last_regime:
                    msg = (f"REGIME SHIFT: {last_regime.upper()} -> {current.upper()} "
                           f"(confidence: {data['confidence']:.0%})")
                    print(f"[{datetime.now():%H:%M:%S}] {msg}")
    
                    if callback:
                        callback(msg, data)
    
                last_regime = current
    
            except Exception as e:
                print(f"Error: {e}")
    
            time.sleep(check_interval)
    
    

    Simple Slack webhook alert

    def slack_alert(msg, data): webhook_url = "https://hooks.slack.com/services/YOUR/WEBHOOK/URL" requests.post(webhook_url, json={"text": msg})

    Start monitoring (checks every 5 min)

    monitor_regime(callback=slack_alert)

    Step 4: Combine with Market Overview

    Get full market context alongside the regime:

    def get_market_context():
        """Fetch regime + market overview in parallel."""
        regime = get_regime()
    
        overview_resp = requests.get(f"{API_BASE}/market/overview", timeout=10)
        overview = overview_resp.json()
    
        return {
            "regime": regime["regime"],
            "confidence": regime["confidence"],
            "btc_price": overview["btc"]["price"],
            "btc_change_24h": overview["btc"]["priceChange24hPct"],
            "eth_price": overview["eth"]["price"],
            "fear_greed": overview["fearGreedIndex"],
            "fear_greed_label": overview["fearGreedLabel"],
            "btc_dominance": overview["btcDominance"],
        }
    
    ctx = get_market_context()
    print(json.dumps(ctx, indent=2))

    Step 5: Simple Backtest Framework

    Compare regime-filtered vs unfiltered returns:

    def backtest_regime_filter(prices, regimes):
        """
        Simple backtest: compare buy-and-hold vs regime-filtered holding.
    
        prices: list of daily close prices
        regimes: list of regime strings (same length as prices)
        """
        # Buy and hold
        bnh_return = (prices[-1] / prices[0] - 1) * 100
    
        # Regime-filtered: only hold during bull, half during chop, flat during bear
        capital = 1.0
        position = 0.0
    
        for i in range(1, len(prices)):
            regime = regimes[i-1]
            target_exposure = {"bull": 1.0, "chop": 0.4, "bear": 0.0}.get(regime, 0.5)
    
            # Adjust position
            daily_return = prices[i] / prices[i-1] - 1
            capital += position * daily_return
            position = capital * target_exposure
    
        regime_return = (capital - 1.0) * 100
    
        print(f"Buy & Hold: {bnh_return:+.1f}%")
        print(f"Regime-Filtered: {regime_return:+.1f}%")
        print(f"Alpha: {regime_return - bnh_return:+.1f}%")

    Pro Features

    The free tier gives you regime classification with a 15-minute delay. For production bots, Pro ($49/mo) unlocks:

    There's also an npm SDK for TypeScript/Node.js: npm install getregime

    Next Steps