Kaique Mitsuo Silva Yamamoto
CriptoTrading automatizado

Freqtrade: Bot Open-Source Completo para Cripto

Guia prático do Freqtrade: instalação, criação de estratégias em Python, backtesting, otimização com Hyperopt, FreqAI com machine learning, paper trading e deploy em produção.

Freqtrade é o framework open-source mais completo para trading automatizado em cripto. Desenvolvido em Python, inclui tudo em um único projeto: estratégias customizáveis, backtesting com dados reais, otimização de parâmetros, controle via Telegram/WebUI e deploy em produção.

  • GitHub: freqtrade/freqtrade
  • Exchanges suportadas: Binance, Bybit, OKX, KuCoin, Gate.io, Kraken, Coinbase e mais de 100 outras (via CCXT)
  • Licença: GPL-3.0 (gratuito e open-source)

Instalação

# Opção 1: Docker (recomendado para produção)
docker pull freqtradeorg/freqtrade:stable

# Opção 2: pip (mais fácil para desenvolvimento)
pip install freqtrade

# Criar estrutura de pastas
freqtrade create-userdir --userdir user_data

# Criar arquivo de configuração
freqtrade new-config --config user_data/config.json

Configuração (config.json)

{
    "max_open_trades": 3,
    "stake_currency": "USDT",
    "stake_amount": 100,
    "tradable_balance_ratio": 0.99,
    "fiat_display_currency": "BRL",
    "timeframe": "1h",
    "dry_run": true,
    "dry_run_wallet": 1000,
    "exchange": {
        "name": "bybit",
        "key": "",
        "secret": "",
        "ccxt_config": {
            "defaultType": "spot"
        }
    },
    "telegram": {
        "enabled": true,
        "token": "SEU_TOKEN_TELEGRAM",
        "chat_id": "SEU_CHAT_ID"
    },
    "api_server": {
        "enabled": true,
        "listen_ip_address": "127.0.0.1",
        "listen_port": 8080
    },
    "bot_name": "meu-bot",
    "initial_state": "running"
}

dry_run: true = paper trading (sem capital real). Sempre comece assim.


Criando uma Estratégia

# user_data/strategies/MinhaEstrategia.py
from freqtrade.strategy import IStrategy, IntParameter, DecimalParameter
import talib.abstract as ta
import pandas as pd

class MinhaEstrategia(IStrategy):

    # Configurações da estratégia
    timeframe        = '1h'
    startup_candle_count = 200   # Candles necessários para indicadores aquecidos
    can_short        = False     # True para estratégias com short

    # ROI (Return on Investment): metas de lucro por tempo
    minimal_roi = {
        "0":   0.10,   # Vende se lucro ≥ 10% em qualquer momento
        "60":  0.05,   # Vende se lucro ≥ 5% após 60 min
        "120": 0.02,   # Vende se lucro ≥ 2% após 120 min
        "240": 0,      # Vende sem lucro após 240 min
    }

    # Stop Loss
    stoploss = -0.05   # Stop de 5%

    # Trailing Stop
    trailing_stop          = True
    trailing_stop_positive = 0.02   # Ativa trailing após 2% de lucro
    trailing_stop_positive_offset = 0.03

    # Parâmetros otimizáveis (usados pelo Hyperopt)
    rsi_buy  = IntParameter(20, 40, default=30, space="buy")
    rsi_sell = IntParameter(55, 80, default=65, space="sell")
    ema_len  = IntParameter(100, 250, default=200, space="buy")

    def populate_indicators(self, dataframe: pd.DataFrame, metadata: dict) -> pd.DataFrame:
        # RSI
        dataframe['rsi'] = ta.RSI(dataframe, timeperiod=14)

        # EMAs
        dataframe['ema_fast'] = ta.EMA(dataframe, timeperiod=50)
        dataframe['ema_slow'] = ta.EMA(dataframe, timeperiod=self.ema_len.value)

        # MACD
        macd = ta.MACD(dataframe)
        dataframe['macd']   = macd['macd']
        dataframe['signal'] = macd['macdsignal']

        # Bollinger Bands
        bolinger = ta.BBANDS(dataframe, timeperiod=20)
        dataframe['bb_upper'] = bolinger['upperband']
        dataframe['bb_lower'] = bolinger['lowerband']

        # ATR para stop dinâmico
        dataframe['atr'] = ta.ATR(dataframe, timeperiod=14)

        return dataframe

    def populate_entry_trend(self, dataframe: pd.DataFrame, metadata: dict) -> pd.DataFrame:
        dataframe.loc[
            (
                (dataframe['rsi'] < self.rsi_buy.value) &           # RSI oversold
                (dataframe['close'] > dataframe['ema_slow']) &       # Acima da EMA lenta
                (dataframe['macd'] > dataframe['signal']) &          # MACD bullish
                (dataframe['volume'] > 0)                            # Volume positivo
            ),
            'enter_long'
        ] = 1
        return dataframe

    def populate_exit_trend(self, dataframe: pd.DataFrame, metadata: dict) -> pd.DataFrame:
        dataframe.loc[
            (
                (dataframe['rsi'] > self.rsi_sell.value) |           # RSI overbought
                (dataframe['macd'] < dataframe['signal'])            # MACD bearish
            ),
            'exit_long'
        ] = 1
        return dataframe

Backtesting

# Baixar dados históricos primeiro
freqtrade download-data \
    --exchange bybit \
    --pairs BTC/USDT ETH/USDT \
    --timeframes 1h \
    --days 365

# Rodar backtesting
freqtrade backtesting \
    --strategy MinhaEstrategia \
    --config user_data/config.json \
    --timerange 20230101-20231231 \
    --fee 0.001

Saída:

BACKTESTING REPORT
==================
Pair       | Trades | Win% | Profit | Drawdown | Sharpe
BTC/USDT   |   73   | 53%  | 18.4%  |  -7.8%   |  1.42
ETH/USDT   |   81   | 49%  | 12.1%  |  -9.2%   |  1.18

SUMMARY METRICS
================
Backtesting from: 2023-01-01 00:00:00
Backtesting to:   2023-12-31 00:00:00
Total trades:     154
Final capital:    US$ 1,306.80 (+30.7%)
Max Drawdown:     -9.2%
Sharpe Ratio:     1.31

Hyperopt: Otimização Automática de Parâmetros

O Hyperopt encontra automaticamente os melhores parâmetros para a estratégia.

freqtrade hyperopt \
    --strategy MinhaEstrategia \
    --hyperopt-loss SharpeHyperOptLoss \
    --spaces buy sell \
    --epochs 300 \
    --timerange 20230101-20231231

Funções de perda disponíveis:

Loss FunctionOtimiza para
SharpeHyperOptLossMelhor Sharpe Ratio (recomendado)
SortinoHyperOptLossMelhor Sortino (menos downside risk)
MaxDrawDownHyperOptLossMenor drawdown máximo
ProfitDrawDownHyperOptLossEquilíbrio lucro × drawdown

Resultado:

Best result:
rsi_buy=27, rsi_sell=62, ema_len=178
Profit: 24.3% | Drawdown: -7.1% | Sharpe: 1.68

Atenção: sempre valide os parâmetros otimizados em dados out-of-sample. Parâmetros otimizados demais podem ser overfitting.


FreqAI: Machine Learning Integrado

FreqAI é o módulo de IA do Freqtrade. Treina modelos de machine learning com dados históricos e os usa para prever direção do preço.

# Adicione à estratégia para usar FreqAI
class MinhaEstrategiaML(IStrategy):

    # Ativar FreqAI
    freqai = {
        "enabled": True,
        "purge_old_models": True,
        "train_period_days": 30,
        "backtest_period_days": 7,
        "identifier": "modelo-rsi-ema",
        "feature_parameters": {
            "include_timeframes": ["5m", "1h", "1d"],
            "include_corr_pairlist": ["BTC/USDT", "ETH/USDT"],
            "label_period_candles": 24,
            "include_shifted_candles": 2,
        },
        "data_split_parameters": {
            "test_size": 0.25,
        },
        "model_training_parameters": {
            "n_estimators": 1000,
            "learning_rate": 0.02,
        },
    }

    def feature_engineering_expand_all(self, dataframe, period, metadata, **kwargs):
        dataframe['%-rsi'] = ta.RSI(dataframe, timeperiod=period)
        dataframe['%-mfi'] = ta.MFI(dataframe, timeperiod=period)
        dataframe['%-macd'] = ta.MACD(dataframe)['macd']
        return dataframe

    def set_freqai_targets(self, dataframe, metadata, **kwargs):
        # Prever retorno futuro em 24 candles
        dataframe['&-fut_return'] = (
            dataframe['close'].shift(-24) / dataframe['close'] - 1
        ).fillna(0)
        return dataframe

    def populate_entry_trend(self, df, metadata):
        df.loc[df['&-fut_return_mean'] > 0.02, 'enter_long'] = 1
        return df

Modelos suportados: LightGBM, XGBoost, CatBoost, scikit-learn (RandomForest, SVM, etc.), PyTorch (experimental).


Paper Trading (Dry Run)

# Garantir dry_run: true no config.json
freqtrade trade \
    --strategy MinhaEstrategia \
    --config user_data/config.json

Monitore via:

  • Telegram: comandos /profit, /status, /trades
  • WebUI: acesse http://localhost:8080 (FreqUI)

Deploy em Produção

# Mudar dry_run para false no config.json
# Adicionar API keys reais

# Rodar com Docker (recomendado)
docker compose up -d freqtrade

# Ou diretamente:
freqtrade trade \
    --strategy MinhaEstrategia \
    --config user_data/config.json

Checklist antes do deploy:

☐ Backtesting positivo em pelo menos 1 ano de dados
☐ Validação out-of-sample (dados não usados no treino) positiva
☐ Paper trading por mínimo 30 dias
☐ API keys configuradas com permissão mínima (sem saque)
☐ Telegram configurado para receber alertas
☐ Bot rodando em servidor com uptime garantido (VPS)
☐ Monitoramento ativo (acompanhe pelo menos 1x por dia)
☐ Capital inicial pequeno (escale conforme confia na estratégia)

Próximos Passos


Aviso Legal: Conteúdo educativo. Resultados de backtesting não garantem performance futura. Não constitui recomendação de investimento.

On this page