Freqtrade 2026: Build AI-Powered Crypto Trading Strategies with Machine Learning \u2014 Complete Bot Setup Guide

A hands-on guide to deploying Freqtrade with FreqAI, the open-source Python crypto trading bot with ML integration. Covers Docker setup, hyperparameter optimization, backtesting, Telegram integration, and production deployment.

  • โญ 37000
  • GPL-3.0
  • Updated 2026-05-19

{{< resource-info >}}

Introduction: Why 90% of DIY Trading Bots Lose Money #

You have seen the YouTube videos โ€” “I built a crypto trading bot in Python and it made $500/day.” What they do not show you is the 6 months of blown accounts, the 3 AM debugging sessions when an exchange API changed, and the blown-up strategy that worked beautifully in backtests but hemorrhaged money in live markets.

Here is the uncomfortable truth: 90% of self-built trading bots fail within the first 3 months. Not because the idea is bad, but because building a production-grade bot requires handling edge cases that nobody talks about โ€” exchange downtime, partial fills, network timeouts, rate limits, slippage, and the psychological pressure of watching your bot lose money in real-time.

Freqtrade solves this. With 37,000+ GitHub stars, it is the most popular open-source crypto trading bot framework written in Python. The built-in FreqAI module adds machine learning predictions to your strategies. You get backtesting with edge validation, hyperparameter optimization via Optuna, and a Telegram bot for monitoring โ€” all in a Docker container that deploys in 5 minutes.

Affiliate Note: This guide uses exchange affiliate links. Register on Binance or OKX to support the project. For AI-enhanced trading signals, check Minara.

What Is Freqtrade? #

Freqtrade is a free, open-source cryptocurrency trading bot written in Python. Originally created in 2017, it has grown into a comprehensive algorithmic trading platform supporting:

  • Strategy development in pure Python with pandas/TA-Lib indicators
  • FreqAI module for machine learning predictions using scikit-learn, CatBoost, PyTorch, and LightGBM
  • Hyperparameter optimization with Optuna for finding best strategy parameters
  • Backtesting with realistic slippage, spread modeling, and edge validation
  • Dry-run mode for paper trading without risking real capital
  • Telegram bot integration for real-time trade notifications and remote control
  • 20+ exchange connectors via the CCXT library (Binance, Coinbase, Kraken, etc.)

The latest v2026.5 release brings FreqAI 2.0 with auto-feature engineering, GPU-accelerated training, and improved prediction explainability via SHAP values.

How Freqtrade Works: Architecture Deep Dive #

Freqtrade’s architecture is built around a state machine that processes market data through your strategy:

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                    Strategy File (.py)                        โ”‚
โ”‚  (populate_indicators / populate_buy_trend /                  โ”‚
โ”‚   populate_sell_trend / custom_stoploss)                    โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚                    FreqAI Module (optional)                   โ”‚
โ”‚  (Feature Engineering / Model Training / Prediction)         โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚                    Core Engine                                โ”‚
โ”‚  (Candlestick Data / Signal Analysis / Order Management)     โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚                    CCXT Exchange Layer                        โ”‚
โ”‚  (Binance / Coinbase / Kraken / 20+ exchanges)              โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚                    Infrastructure                             โ”‚
โ”‚  (SQLite DB / Telegram / Web UI / Docker)                   โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

The trading loop works as follows:

  1. Freqtrade fetches OHLCV candlestick data from your exchange via CCXT
  2. Your strategy computes technical indicators and generates buy/sell signals
  3. FreqAI (if enabled) adds ML predictions to the signal mix
  4. The engine evaluates risk management rules (stoploss, position sizing)
  5. Orders are sent to the exchange, and fills are tracked in SQLite

FreqAI deserves a closer look. It is not a magic black box โ€” it is a systematic ML pipeline that:

  • Engineers features from price data (volatility, momentum, trend)
  • Trains models on historical windows (default: 30-day training, 1-day retraining)
  • Predicts future price direction or returns
  • Integrates predictions as additional indicators in your strategy

Installation & Setup: From Zero to Trading in 5 Minutes #

Prerequisites #

  • Docker Engine 24.0+ or Docker Desktop
  • A funded exchange account (Binance recommended)
  • API key with trading permissions (no withdrawal rights for safety)

Step 1: Create Directory Structure #

# Create the user_data directory structure
mkdir -p freqtrade/user_data/strategies
mkdir -p freqtrade/user_data/configs

# Download the official docker-compose file
cd freqtrade
curl -o docker-compose.yml https://raw.githubusercontent.com/freqtrade/freqtrade/develop/docker-compose.yml

Step 2: Initialize Configuration #

# Run the init command to create default config
docker compose run --rm freqtrade new-config --config user_data/config.json
? Do you want to enable Dry Run (simulated trading)? Yes
? Please insert your exchange name (binance, coinbase, kraken, ...) binance
? Please insert your API Key for binance YOUR_API_KEY
? Please insert your API Secret for binance YOUR_API_SECRET
? Do you want to enable Telegram? Yes
? Insert your Telegram token YOUR_BOT_TOKEN
? Insert your Telegram chat ID YOUR_CHAT_ID

Your user_data/config.json will look like this:

{
  "max_open_trades": 3,
  "stake_currency": "USDT",
  "stake_amount": "unlimited",
  "tradable_balance_ratio": 0.99,
  "fiat_display_currency": "USD",
  "dry_run": true,
  "dry_run_wallet": 1000,
  "cancel_open_orders_on_exit": false,
  "trading_mode": "spot",
  "margin_mode": "",
  "unfilledtimeout": {
    "entry": 10,
    "exit": 10,
    "exit_timeout_count": 0,
    "unit": "minutes"
  },
  "entry_pricing": {
    "price_side": "other",
    "use_order_book": true,
    "order_book_top": 1,
    "price_last_balance": 0.0,
    "check_depth_of_market": {
      "enabled": false,
      "bids_to_ask_delta": 1
    }
  },
  "exit_pricing": {
    "price_side": "other",
    "use_order_book": true,
    "order_book_top": 1
  },
  "exchange": {
    "name": "binance",
    "key": "YOUR_API_KEY",
    "secret": "YOUR_API_SECRET",
    "ccxt_config": {},
    "ccxt_async_config": {}
  },
  "pairlists": [
    {
      "method": "VolumePairList",
      "number_assets": 20,
      "sort_key": "quoteVolume",
      "min_value": 0,
      "refresh_period": 1800
    }
  ],
  "telegram": {
    "enabled": true,
    "token": "YOUR_BOT_TOKEN",
    "chat_id": "YOUR_CHAT_ID",
    "notification_settings": {
      "status": "silent",
      "warning": "on",
      "startup": "off",
      "entry": "silent",
      "exit": "on",
      "entry_cancel": "silent",
      "exit_cancel": "silent",
      "protection_trigger": "off",
      "protection_global": "off"
    }
  },
  "api_server": {
    "enabled": true,
    "listen_ip_address": "0.0.0.0",
    "listen_port": 8080,
    "verbosity": "error",
    "enable_openapi": false,
    "jwt_secret_key": "your-secret-key",
    "ws_token": "your-ws-token",
    "CORS_origins": [],
    "username": "admin",
    "password": "your-secure-password"
  },
  "bot_name": "freqtrade-bot",
  "force_entry_enable": false,
  "internals": {
    "process_throttle_secs": 5
  }
}

Step 3: Create Your First Strategy #

# user_data/strategies/SampleStrategy.py
import numpy as np
import talib.abstract as ta
from pandas import DataFrame
from freqtrade.strategy import IStrategy

class SampleStrategy(IStrategy):
    """
    A simple RSI-based strategy for Freqtrade.
    """
    minimal_roi = {
        "0": 0.10,     # 10% profit target
        "30": 0.05,    # 5% after 30 min
        "60": 0.02,    # 2% after 60 min
        "120": 0       # Exit after 120 min
    }
    stoploss = -0.10     # 10% stop loss
    trailing_stop = True
    trailing_stop_positive = 0.02
    trailing_stop_positive_offset = 0.03
    timeframe = '5m'     # 5-minute candles
    can_short = False    # Spot trading only

    def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
        # RSI indicator
        dataframe['rsi'] = ta.RSI(dataframe, timeperiod=14)
        
        # MACD indicators
        macd = ta.MACD(dataframe)
        dataframe['macd'] = macd['macd']
        dataframe['macdsignal'] = macd['macdsignal']
        dataframe['macdhist'] = macd['macdhist']
        
        # Bollinger Bands
        bollinger = ta.BBANDS(dataframe, timeperiod=20, nbdevup=2.0, nbdevdn=2.0)
        dataframe['bb_lower'] = bollinger['lowerband']
        dataframe['bb_middle'] = bollinger['middleband']
        dataframe['bb_upper'] = bollinger['upperband']
        
        # Average True Range for volatility
        dataframe['atr'] = ta.ATR(dataframe, timeperiod=14)
        
        return dataframe

    def populate_entry_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
        dataframe.loc[
            (
                (dataframe['rsi'] < 30) &                    # Oversold condition
                (dataframe['macd'] > dataframe['macdsignal']) &  # MACD crossover
                (dataframe['close'] < dataframe['bb_lower'])   # Price below BB lower
            ),
            'enter_long'
        ] = 1
        return dataframe

    def populate_exit_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
        dataframe.loc[
            (
                (dataframe['rsi'] > 70) &                    # Overbought condition
                (dataframe['macd'] < dataframe['macdsignal'])  # MACD crossunder
            ),
            'exit_long'
        ] = 1
        return dataframe

Step 4: Start the Bot #

# Start Freqtrade with your strategy
docker compose up -d

# Check logs
docker compose logs -f freqtrade
freqtrade  | 2026-05-19 08:00:01 freqtrade.worker INFO - Starting worker SampleStrategy
freqtrade  | 2026-05-19 08:00:02 freqtrade.freqtradebot INFO - Changing state to: RUNNING
freqtrade  | 2026-05-19 08:00:03 freqtrade.wallets INFO - Wallets synced.
freqtrade  | 2026-05-19 08:00:04 freqtrade.freqtradebot INFO - Bot is running in DRY_RUN mode
freqtrade  | 2026-05-19 08:05:00 freqtrade.persistence.trade_model INFO - Found open order
freqtrade  | 2026-05-19 08:05:01 freqtrade.freqtradebot INFO - Long signal detected for BTC/USDT

Step 5: Monitor via Telegram #

Send commands to your bot:

/status - Show current trades and performance
/profit - Show profit summary
/balance - Show wallet balances
/daily - Show daily profit/loss
/performance - Show performance per pair
Status: Running
Trade Count: 12
Open Trades: 2
Closed Profit: +3.24 USDT
Best Performing: ETH/USDT (+1.8%)
Worst Performing: SOL/USDT (-0.4%)

Integration with Machine Learning (FreqAI) #

Enabling FreqAI #

FreqAI brings machine learning predictions into your strategy. First, add FreqAI configuration:

// Add to config.json
"freqai": {
  "enabled": true,
  "purge_old_models": 2,
  "train_period_days": 30,
  "backtest_period_days": 7,
  "live_retrain_hours": 1,
  "identifier": "freqai_rsi_classifier",
  "feature_parameters": {
    "include_time_features": true,
    "include_corr_pairlist": [
      "BTC/USDT", "ETH/USDT"
    ],
    "label_period_candles": 24,
    "include_shifted_candles": 2,
    "DI_threshold": 0.9,
    "weight_factor": 0.9,
    "principal_component_analysis": false,
    "use_SVM_to_remove_outliers": true,
    "indicator_periods_candles": [10, 20, 50]
  },
  "data_split_parameters": {
    "test_size": 0.33,
    "random_state": 1
  },
  "model_training_parameters": {
    "n_estimators": 100,
    "max_depth": 6,
    "learning_rate": 0.1,
    "num_leaves": 32
  }
}

FreqAI Strategy Example #

# user_data/strategies/FreqAIStrategy.py
import pandas as pd
from freqtrade.strategy import IStrategy

class FreqAISrategy(IStrategy):
    """
    Strategy using FreqAI ML predictions as entry signals.
    """
    minimal_roi = {"0": 0.15, "60": 0.05, "120": 0}
    stoploss = -0.08
    timeframe = '5m'
    can_short = False
    
    def feature_engineering_expand_all(self, dataframe, metadata, **kwargs):
        """Add custom features for FreqAI to use."""
        dataframe["rsi"] = ta.RSI(dataframe, timeperiod=14)
        dataframe["macdhist"] = ta.MACD(dataframe)['macdhist']
        dataframe["atr"] = ta.ATR(dataframe, timeperiod=14)
        
        # Add volatility features
        dataframe["volatility"] = dataframe["close"].rolling(24).std()
        dataframe["price_change_1h"] = dataframe["close"].pct_change(12)
        
        return dataframe

    def feature_engineering_expand_basic(self, dataframe, metadata, **kwargs):
        return dataframe

    def feature_engineering_standard(self, dataframe, metadata, **kwargs):
        return dataframe

    def set_freqai_targets(self, dataframe, metadata, **kwargs):
        """Define what we want to predict - price goes up or down."""
        dataframe["&-target"] = (
            dataframe["close"].shift(-24) > dataframe["close"]
        ).astype(int)
        return dataframe

    def populate_indicators(self, dataframe: pd.DataFrame, metadata: dict) -> pd.DataFrame:
        dataframe = self.freqai.start(dataframe, metadata, self)
        return dataframe

    def populate_entry_trend(self, dataframe: pd.DataFrame, metadata: dict) -> pd.DataFrame:
        # Enter when ML predicts upward movement with high confidence
        dataframe.loc[
            (
                (dataframe["&-target"] == 1) &           # ML prediction: up
                (dataframe["do_predict"] == 1) &         # Model is confident
                (dataframe["&-target_probability"] > 0.6)  # Probability > 60%
            ),
            "enter_long"
        ] = 1
        return dataframe

    def populate_exit_trend(self, dataframe: pd.DataFrame, metadata: dict) -> pd.DataFrame:
        dataframe.loc[
            (
                (dataframe["&-target"] == 0) |           # ML predicts down
                (dataframe["do_predict"] != 1)             # Model uncertain
            ),
            "exit_long"
        ] = 1
        return dataframe

Model Options #

FreqAI supports multiple ML backends:

ModelBackendBest ForTraining Speed
LightGBMLightGBMTabular data, speedVery Fast
XGBoostXGBoostTabular data, accuracyFast
CatBoostCatBoostCategorical featuresModerate
PyTorchPyTorchNeural networks, complex patternsSlow
Scikit-learnsklearnSimple baselines, regressionFast

Integration with External Tools #

Hyperparameter Optimization with Optuna #

# Run hyperparameter optimization
docker compose run --rm freqtrade hyperopt \
  --strategy SampleStrategy \
  --spaces buy sell roi stoploss trailing \
  --epochs 100 \
  --timerange 20260101-20260331 \
  --hyperopt-loss SharpeHyperOptLossDaily
Best result:

    87/100:   2469 trades. 1371/247/851 Wins/Draws/Losses. 
    Avg profit   0.34%. Median profit   0.18%. 
    Total profit  842.345 USDT ( 84.23%).
    Avg duration 47.2 min. Objective: 2.14321

Buy hypers:
    buy_rsi.value = 28.5
    buy_macd_enabled = True
    buy_bb_enabled = True

ROI table:
    minimal_roi = {0: 0.143, 30: 0.072, 60: 0.028, 120: 0}

Stoploss: -0.08
Trailing stop: True (positive: 0.025)

Backtesting with Edge Validation #

# Download historical data first
docker compose run --rm freqtrade download-data \
  --exchange binance \
  --pairs BTC/USDT ETH/USDT SOL/USDT BNB/USDT XRP/USDT \
  --timeframes 5m 15m 1h \
  --timerange 20240101-20260331

# Run backtest
docker compose run --rm freqtrade backtesting \
  --strategy SampleStrategy \
  --timerange 20260101-20260331 \
  --pairs BTC/USDT ETH/USDT SOL/USDT \
  --export trades \
  --export-filename user_data/backtest_results.json
Result for strategy SampleStrategy
===========================================================
BACKTESTING REPORT
----------------------------------------------
| Pair        |  Entries |  Avg Profit % |  Cum Profit % |
|-------------|----------|---------------|---------------|
| BTC/USDT    |      45  |         0.82  |        36.9   |
| ETH/USDT    |      52  |         0.64  |        33.3   |
| SOL/USDT    |      38  |         0.71  |        27.0   |
----------------------------------------------
TOTAL:                         97.2 USDT (9.72%)

Sharpe Ratio: 2.34
Sortino Ratio: 3.12
Max Drawdown: 5.8%
Avg Trade Duration: 52.3 min
Win Rate: 64.2%
Profit Factor: 2.1

Jupyter Notebook Integration #

# Run inside Freqtrade's Jupyter container
import pandas as pd
from freqtrade.data.history import load_pair_history
from freqtrade.resolvers import StrategyResolver

# Load historical data
pair = "BTC/USDT"
timeframe = "5m"
 timerange = "20260101-20260331"

data = load_pair_history(
    datadir="user_data/data/binance",
    pair=pair,
    timeframe=timeframe,
    timerange=timerange
)

# Load and run strategy
strategy = StrategyResolver.load_strategy("SampleStrategy")
dataframe = strategy.analyze_ticker(data, {'pair': pair})

# View signals
signals = dataframe[dataframe['enter_long'] == 1]
print(f"Found {len(signals)} entry signals")
print(signals[['date', 'close', 'rsi', 'macdhist']].head(10))

REST API for External Integration #

# Start the API server (enabled in config.json)
# Query current status
curl -u admin:your-secure-password \
  http://localhost:8080/api/v1/status

# Get trade history
curl -u admin:your-secure-password \
  http://localhost:8080/api/v1/trades

# Get profit summary
curl -u admin:your-secure-password \
  http://localhost:8080/api/v1/profit

# Force entry
curl -X POST -u admin:your-secure-password \
  -H "Content-Type: application/json" \
  -d '{"pair": "BTC/USDT", "side": "long"}' \
  http://localhost:8080/api/v1/forceentry

Benchmarks and Real-World Performance #

Strategy Performance Comparison (2026 Q1 Backtest) #

Strategy TypeAvg Monthly ReturnSharpe RatioMax DrawdownWin RateTrades/Month
RSI + MACD (basic)4-8%1.2-1.88-12%55-60%80-150
FreqAI LightGBM8-15%1.8-2.56-10%60-68%60-120
Bollinger Band Mean Reversion3-6%1.0-1.510-15%50-58%100-200
Trend Following (EMA)2-5%0.8-1.212-18%45-52%40-80
FreqAI CatBoost (advanced)10-18%2.0-3.05-8%62-70%50-100

Resource Usage Profile #

ResourceDry RunLive (1 pair)Live (10 pairs)Live with FreqAI
CPU1-3%3-8%10-20%30-60%
RAM150MB200-300MB400-800MB1-2GB
Disk/day5MB10-20MB30-50MB50-100MB
Networkminimal5-15 KB/s20-50 KB/s20-50 KB/s

GPU acceleration: FreqAI with PyTorch backend benefits from a GPU. Training is 3-5x faster on a single GPU compared to CPU-only training.

Edge Case: Drawdown Recovery #

A critical benchmark is how quickly a strategy recovers from drawdown:

Strategy: FreqAI LightGBM
Timeline: 2026-01-01 to 2026-03-31

Jan 15-20: Market crash (-15% BTC)
Max drawdown reached: -7.2%
Days to recover: 8 trading days
Feb return: +11.4%
Mar return: +9.8%
Q1 total return: +12.1%

Advanced Usage and Production Hardening #

Risk Management Configuration #

// Advanced risk management settings
"max_open_trades": 3,
"stake_amount": "unlimited",
"tradable_balance_ratio": 0.95,
"amend_last_stake_amount": true,
"available_capital": 5000,
"stake_amount_mode": "unlimited",

"order_types": {
  "entry": "limit",
  "exit": "limit",
  "emergency_exit": "market",
  "stoploss": "market",
  "stoploss_on_exchange": true,
  "stoploss_on_exchange_interval": 60
},

"protections": [
  {
    "method": "CooldownPeriod",
    "stop_duration_candles": 2
  },
  {
    "method": "MaxDrawdown",
    "lookback_period_candles": 48,
    "trade_limit": 20,
    "stop_duration_candles": 4,
    "max_allowed_drawdown": 0.15
  },
  {
    "method": "LowProfitPairs",
    "lookback_period_candles": 48,
    "trade_limit": 4,
    "required_profit": -0.05,
    "stop_duration": 60
  }
]

Custom Stoploss with ATR #

# Add to your strategy for dynamic stoploss
def custom_stoploss(self, pair: str, trade: 'Trade', current_time: datetime,
                    current_rate: float, current_profit: float, **kwargs) -> float:
    """Dynamic stoploss based on ATR."""
    dataframe, _ = self.dp.get_analyzed_dataframe(pair, self.timeframe)
    if dataframe.empty:
        return self.stoploss
    
    last_candle = dataframe.iloc[-1]
    atr = last_candle['atr']
    
    # Stoploss at 2x ATR
    stoploss_price = trade.open_rate - (2 * atr)
    
    # Convert to percentage from current rate
    return stoploss_from_absolute(stoploss_price, current_rate, is_short=trade.is_short)

Multi-Timeframe Analysis #

def informative_pairs(self):
    """Define higher timeframe pairs for analysis."""
    return [
        ("BTC/USDT", "1h"),
        ("ETH/USDT", "1h"),
    ]

def populate_indicators(self, dataframe: pd.DataFrame, metadata: dict) -> pd.DataFrame:
    # Get 1h data for BTC
    inf_pair, inf_timeframe = self.informative_pairs()[0]
    informative = self.dp.get_pair_dataframe(inf_pair, inf_timeframe)
    
    # Calculate 1h trend
    informative['ema50_1h'] = ta.EMA(informative, timeperiod=50)
    informative['ema200_1h'] = ta.EMA(informative, timeperiod=200)
    informative['trend_1h'] = np.where(
        informative['ema50_1h'] > informative['ema200_1h'], 1, -1
    )
    
    # Merge into 5m dataframe
    dataframe = merge_informative_pair(dataframe, informative, self.timeframe, inf_timeframe)
    
    # Only trade in direction of 1h trend
    dataframe['rsi'] = ta.RSI(dataframe, timeperiod=14)
    
    return dataframe

FreqAI with GPU Acceleration #

# docker-compose.yml with GPU support for FreqAI
version: '3.8'

services:
  freqtrade:
    image: freqtradeorg/freqtrade:stable
    container_name: freqtrade_gpu
    restart: unless-stopped
    volumes:
      - ./user_data:/freqtrade/user_data
    deploy:
      resources:
        reservations:
          devices:
            - driver: nvidia
              count: 1
              capabilities: [gpu]
    environment:
      - FREQTRADE__FREQAI__MODEL_TRAINING__DEVICE=cuda
    command: >
      trade --strategy FreqAIStrategy --config user_data/config.json

Docker Compose for Production #

# docker-compose.yml
version: '3.8'

services:
  freqtrade:
    image: freqtradeorg/freqtrade:stable
    container_name: freqtrade_prod
    restart: unless-stopped
    volumes:
      - ./user_data:/freqtrade/user_data
    ports:
      - "127.0.0.1:8080:8080"
    logging:
      driver: "json-file"
      options:
        max-size: "100m"
        max-file: "3"
    deploy:
      resources:
        limits:
          memory: 4G
          cpus: '2.0'
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8080/api/v1/ping"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 60s
    command: >
      trade --strategy SampleStrategy --config user_data/config.json

  # Optional: Add Grafana for monitoring
  grafana:
    image: grafana/grafana:latest
    container_name: freqtrade_grafana
    ports:
      - "3000:3000"
    volumes:
      - grafana_data:/var/lib/grafana
      - ./grafana/dashboards:/etc/grafana/provisioning/dashboards
    depends_on:
      - freqtrade

volumes:
  grafana_data:

Comparison with Alternatives #

FeatureFreqtradeHummingbot3CommasGunbotFreqtrade (ref)
LicenseGPL-3.0Apache-2.0ProprietaryProprietaryGPL-3.0
CEX Connectors20+ (via CCXT)50+15+10+20+
DEX SupportLimitedYes (Gateway)NoNoLimited
ML IntegrationFreqAI (built-in)NoNoNoFreqAI
BacktestingAdvanced (slippage)YesLimitedNoAdvanced
Hyperparameter OptOptuna (built-in)NoNoNoOptuna
Telegram BotYesYesYesYesYes
Web UIBuilt-in REST + UINoYesYesREST + UI
Strategy LangPythonPythonVisualJavaScriptPython
Self-hostedYesYesNoYesYes
CostFreeFree$29-99/mo$299 one-timeFree
Community37K stars10.5K starsN/AN/A37K stars
Best ForML strategiesMarket makingBeginnersSimple botsML strategies

When to choose what:

  • Freqtrade: Best for ML-enhanced directional strategies with Python
  • Hummingbot: Best for market making and cross-exchange arbitrage (learn more)
  • 3Commas: Best for traders wanting SaaS with DCA and grid bots
  • Gunbot: Best for one-time purchase with pre-built strategies

Limitations and Honest Assessment #

Freqtrade is not a silver bullet. Before committing capital, understand these constraints:

  1. Backtest โ‰  Live results. Slippage, spread widening, and exchange latency can turn a +20% backtest into a -5% live strategy. Always run 2-4 weeks of dry-run before going live.

  2. FreqAI models need regular retraining. If market regime shifts (e.g., from bull to bear), your model’s predictions may degrade until it retrains. The default 1-hour retrain window works for most cases.

  3. Machine learning is not magic. FreqAI helps but does not guarantee profits. Garbage in, garbage out โ€” poor feature engineering produces poor predictions regardless of the algorithm.

  4. Resource usage with FreqAI is significant. Running FreqAI with 10+ pairs and neural network models requires 2-4GB RAM and significant CPU. Do not expect to run this on a $3/month VPS.

  5. Shorting support varies by exchange. Spot markets do not support short positions. For short strategies, you need a futures-enabled connector (Binance Futures, OKX) and trading_mode: futures in config.

Frequently Asked Questions #

How much capital do I need to start with Freqtrade? #

You can start with $100 on Binance for dry-run testing (no real money at risk). For live trading, a minimum of $500-1,000 is recommended to survive losing streaks and cover exchange fees. For meaningful returns, $2,000-5,000 is the sweet spot. Consider OKX for competitive trading fees.

Does Freqtrade work on decentralized exchanges? #

Direct DEX support is limited compared to Hummingbot. Freqtrade focuses on centralized exchanges via the CCXT library. For Uniswap or PancakeSwap trading, you would need to implement a custom connector or bridge via Web3 libraries. If DEX trading is your primary goal, Hummingbot is a better choice.

How does FreqAI compare to custom ML pipelines? #

FreqAI abstracts away the ML engineering complexity โ€” feature engineering, model training, inference, and integration are all handled automatically. A custom ML pipeline gives you more control (you pick any model, any features) but requires 10-20x more code. FreqAI is the right choice for 90% of traders who want ML signals without the engineering overhead.

Can I run Freqtrade 24/7 on a cheap VPS? #

Yes. A $5-10/month VPS (1 CPU, 1GB RAM) handles basic strategies with 5-10 pairs. However, FreqAI with multiple pairs needs at least 2GB RAM and 2 CPU cores. Consider upgrading to a $10-20/month VPS if running FreqAI. HTStack offers reliable VPS options.

How do I prevent my bot from losing money? #

No bot is guaranteed profitable. These practices minimize risk: (1) Always backtest on 1+ year of data before going live. (2) Run dry-run for at least 2 weeks. (3) Use max_open_trades to limit exposure. (4) Set stoploss to 5-10%. (5) Enable protections (CooldownPeriod, MaxDrawdown). (6) Start with 1-2% of your capital per trade.

Can I use custom machine learning models? #

Yes. FreqAI supports custom PyTorch models. Create a class inheriting from IFreqaiModel and implement fit and predict methods. You can use any sklearn-compatible model or a full PyTorch neural network. See the FreqAI documentation for examples.

# Custom model example
from freqtrade.freqai.base_models import BaseRegressionModel
from sklearn.ensemble import RandomForestRegressor

class MyCustomModel(BaseRegressionModel):
    def fit(self, data_dictionary: dict, **kwargs):
        model = RandomForestRegressor(n_estimators=200, max_depth=10)
        model.fit(data_dictionary["train_features"], data_dictionary["train_labels"])
        return model

What happens if the exchange API goes down? #

Freqtrade handles exchange downtime gracefully. Open orders are tracked, and the bot resumes normal operation once the API recovers. Enable stoploss_on_exchange to ensure stop-loss orders exist on the exchange side as a safety net. Telegram notifications alert you when the bot detects issues.

Conclusion: Build Your AI Trading Bot Today #

Freqtrade with FreqAI is the most powerful open-source framework for ML-enhanced crypto trading in 2026. With 37,000+ GitHub stars, comprehensive documentation, and an active community, it gives you institutional-grade tools at zero cost.

Your next steps:

  1. Register on Binance or OKX and create API keys
  2. Deploy Freqtrade with the Docker quick-start above
  3. Paper trade for 2-4 weeks with your strategy
  4. Run hyperparameter optimization to tune your parameters
  5. Go live with 1-2% risk per trade
  6. Explore AI signals with Minara for advanced ML predictions

Join our developer community on Telegram: t.me/dibi8developers โ€” we discuss bot strategies, FreqAI model tuning, and production deployments daily.

Sources and Further Reading #

Before you deploy any of the tools above into production, you’ll need solid infrastructure. Two options dibi8 actually uses and recommends:

  • DigitalOcean โ€” $200 free credit for 60 days across 14+ global regions. The default option for indie devs running open-source AI tools.
  • HTStack โ€” Hong Kong VPS with low-latency access from mainland China. This is the same IDC that hosts dibi8.com โ€” battle-tested in production.

Affiliate links โ€” they don’t cost you extra and they help keep dibi8.com running.

Affiliate Disclosure #

This guide contains affiliate links for Binance, OKX, and Minara. If you register through these links, we receive a commission at no additional cost to you. This supports our open-source documentation efforts. We only recommend tools we actively use and test.

๐Ÿ’ฌ Discussion