Divergência RSI: backtest Python, 3 configurações e +282% em ETH/USDT (4H)

ConfigOB/OSSLTPTradesWRRetornoSharpe
B ★67/331,5%2R11946,2%+282,1%0,99
A67/331,5%3R10640,6%+287,0%0,93
C67/330,75%1,5R14949,7%+161,0%0,90

ETH/USDT:USDT 4H, Bybit Futures, mar/2021 → jul/2026. Buy & Hold ETH no mesmo período: -8,7%.

A divergência RSI é um dos sinais mais estudados em análise técnica - e um dos menos testados com dados reais em PT-BR.

Para mudar isso, construímos um backtester Python event-driven do zero, rodamos um grid search com 48 combinações de parâmetros e medimos o que a estratégia de divergência RSI realmente entrega no ETH/USDT em 5,5 anos de dados históricos.

O código tem 6 arquivos, zero dependência de frameworks externos de backtesting e está publicado no GitHub.

Neste artigo, explicamos como a divergência RSI funciona, mostramos a máquina de estados que detecta o sinal e compartilhamos a conclusão honesta - com mais de 8 anos operando - sobre usar esse indicador em automação.

A divergência RSI funciona em cripto? O que o backtest mostrou

A resposta direta: funciona, com ressalvas importantes. A divergência RSI gerou +282,1% no ETH/USDT 4H entre março de 2021 e julho de 2026 - um período que inclui o bear market de 2022 inteiro e o bull market de 2024. O Buy & Hold do ETH no mesmo período retornou -8,7%.

São 119 operações em cinco anos - uma frequência baixa de sinais, esperada para um indicador RSI configurado para detectar divergências de topo e de fundo.

A taxa de acerto de 46,2% parece baixa, mas o Profit Factor de 1,64 garante que os ganhos médios superam as perdas médias com consistência.

equity curve backtesting RSI divergência ETH USDT Config B
Config B: +282,1% vs Buy & Hold ETH -8,7% (mar/2021 → jul/2026, 119 trades, sem alavancagem)

O que o Sharpe de 0,99 significa na prática

O índice de Sharpe mede o retorno ajustado ao risco. Um Sharpe de 0,99 na divergência RSI significa que, para cada unidade de volatilidade assumida, o sistema gerou quase uma unidade equivalente de retorno.

Na prática, é a diferença entre uma equity curve ascendente e consistente e uma que cresce apenas em mercados favoráveis.

Vernon

💡 Dica do Vernon: A Config A tem retorno maior (+287%) mas Sharpe menor (0,93) e drawdown pior (-28,5%). Escolhi a Config B porque prefiro consistência sobre retorno máximo - especialmente para quem está colocando a estratégia em produção pela primeira vez. Com drawdown máximo de -26,9%, consigo manter a disciplina. Com -28,5%, começo a questionar a estratégia nos momentos errados.

Como funciona a estratégia de divergência RSI

A estratégia de divergência RSI que testamos é a implementação Python fiel à versão Pine Script publicada no TradingView. O backtester Python é o espelho verificável dessa lógica em código executável - qualquer trader pode reproduzir e validar cada sinal nos mesmos dados históricos.

O que é divergência de RSI em cripto?

A divergência RSI ocorre quando o preço e o indicador RSI se movem em direções opostas. Numa divergência de topo, o preço faz um novo máximo enquanto o RSI registra um máximo menor - sinal de que o momentum de compra está se esgotando.

A divergência de fundo é o oposto: novo mínimo no preço, mínimo menos extremo no RSI, indicando esgotamento da pressão vendedora.

Divergência de topo (bearish): o setup em 4 passos

A máquina de estados detecta a divergência RSI bearish em quatro etapas sequenciais obrigatórias:

  • S1: RSI entra na zona de sobrecompra (acima de 67) - a estratégia guarda o high da vela como referência
  • S2: preço faz novo máximo acima do high de referência, mas o RSI está abaixo de 67 - divergência RSI confirmada
  • S3: RSI cruza abaixo da SMA(5) - SINAL SHORT gerado no fechamento da vela
  • Execução: entrada no open da vela seguinte | SL = high da vela de sinal × (1 + 1,5%) | TP = 2R (distância até o SL × 2)
divergência de topo RSI ETH USDT 4H TradingView
Divergência bearish no ETH/USDT 4H: preço renova máximo, RSI não - sinal de enfraquecimento do momentum

Divergência de fundo (bullish): o espelho

O setup bullish é o espelho exato do bearish. O indicador RSI entra na zona de sobrevenda (abaixo de 33) e o preço faz nova mínima enquanto o RSI não acompanha - divergência RSI de fundo confirmada.

O SINAL LONG é gerado quando o RSI cruza acima da SMA(5). O SL fica abaixo do low da vela de sinal com o mesmo ratio de 1,5%, e o TP no dobro da distância.

Qual a diferença entre RSI 70/30 e RSI 67/33?

Os limiares padrão de sobrecompra sobrevenda RSI são 70 e 30. Com limiares de 67/33, as zonas de sobrecompra sobrevenda RSI são atingidas com mais frequência - o que gera mais candidatos a divergência RSI por período.

No grid search de 48 combinações para ETH/USDT 4H, os pares 67/33 dominaram o top cinco por Profit Factor. Os limiares 70/30 geraram menos operações e Sharpe ligeiramente inferior no mesmo par e timeframe.

Se você quer visualizar a divergência RSI em tempo real antes de automatizar, o artigo Como criar uma estratégia Pine Script no TradingView mostra como implementamos esse mesmo sinal sem uma linha de código.

Como construímos o backtester Python (6 arquivos, 0 frameworks externos)

O projeto usa a mesma arquitetura modular do backtester de médias móveis exponenciais, mas com uma diferença central: a divergência RSI é stateful - a estratégia precisa lembrar em que etapa do setup está entre uma vela e outra.

Frameworks genéricos de backtesting assumem que a estratégia é stateless. Por isso, implementamos a máquina de estados do zero em Python puro.

Vernon

💡 Dica do Vernon: Tentei adaptar o backtrader primeiro. O problema é que a divergência RSI precisa rastrear se estamos em S1, S2 ou aguardando o cruzamento do RSI com a SMA - e frameworks genéricos não têm esse conceito de estado persistente entre velas. Escrever a máquina de estados do zero em Python levou menos tempo do que contornar a API de qualquer framework.

Estrutura do projeto

Os seis arquivos do backtester de divergência RSI têm responsabilidades bem definidas:

  • config.py - todos os parâmetros: símbolo, timeframe, OB/OS, SL%, TP multiplier, comissão (0,055% taker Bybit), capital inicial
  • indicadores.py - RSI Wilder (ewm com alpha=1/n, idêntico ao ta.rsi() do TradingView) + SMA de suavização do RSI
  • strategy.py - máquina de estados da divergência RSI + dataclass Operacao
  • backtester.py - loop event-driven: download via CCXT, detecção de sinal no close[i], execução no open[i+1], SL/TP verificados no high/low
  • optimizador.py - grid search com 48 combinações, download único dos dados históricos
  • gerar_equity_curve.py - curva de capital vs Buy & Hold com tema dark CriptoMatiko

Para quem quer entender o trading algorítmico com Python além do backtesting - desde a escolha de exchange até a execução de ordens ao vivo - o artigo cobre o caminho completo.

O coração: a máquina de estados em 4 passos

O arquivo strategy.py é o diferencial desta implementação. A diferença-chave em relação ao backtester EMA: a estratégia de divergência RSI não faz FLIP automático.

Ela aguarda o SL ou TP ser atingido antes de iniciar um novo setup na direção oposta - o que reduz o número de operações e aumenta a qualidade de cada entrada.

"""
Estratégia: Divergência RSI (4H) — Bybit Futures
Máquina de estados em 4 passos.
Referência Pine Script: criptomatiko.com/criar-estrategia-pine-script-tradingview

Setup SHORT (divergência de topo):
  S1: RSI > OB  → guarda ref_high
  S2: high > ref_high E RSI <= OB → divergência RSI confirmada
  S3: RSI cruza abaixo da SMA(5) → SINAL SHORT
  SL = high_sinal × (1 + sl_pct/100)
  TP = entrada - (SL - entrada) × tp_mult

Setup LONG (espelho do SHORT):
  S1: RSI < OS  → guarda ref_low
  S2: low < ref_low E RSI >= OS → divergência RSI confirmada
  S3: RSI cruza acima da SMA(5) → SINAL LONG
  SL = low_sinal × (1 - sl_pct/100)
  TP = entrada + (entrada - SL) × tp_mult
"""

import math
from dataclasses import dataclass
from typing import Optional

_NEUTRO = 0;  _SHORT_S1 = 1;  _SHORT_S2 = 2
_LONG_S1 = 3; _LONG_S2 = 4

@dataclass
class Operacao:
    tempo_entrada:  str
    preco_entrada:  float
    direcao:        str
    tamanho:        float
    preco_sl:       Optional[float]
    preco_tp:       Optional[float]
    tempo_saida:    Optional[str]   = None
    preco_saida:    Optional[float] = None
    motivo_saida:   Optional[str]   = None
    lucro_usd:      float           = 0.0
    lucro_pct:      float           = 0.0

class EstrategiaRSIDivergencia:

    def __init__(self, sl_pct, tp_mult, comissao_pct, tamanho_pct,
                 lookback_limit, rsi_ob, rsi_os, operar_short=True):
        self.sl_pct = sl_pct;  self.tp_mult = tp_mult
        self.comissao_pct = comissao_pct;  self.tamanho_pct = tamanho_pct
        self.lookback_limit = lookback_limit
        self.rsi_ob = rsi_ob;  self.rsi_os = rsi_os
        self.operar_short = operar_short
        self._state = _NEUTRO;  self._ref_high = None;  self._ref_low = None
        self._lookback_count = 0;  self.sl_pendente = None;  self.posicao = None

    def processar_vela(self, rsi_ant, rsi_sma_ant, rsi, rsi_sma, high, low):
        """Retorna 'VENDER', 'COMPRAR' ou None. sl_pendente é definido junto ao sinal."""
        if any(math.isnan(v) for v in [rsi_ant, rsi_sma_ant, rsi, rsi_sma]):
            return None
        cruzou_abaixo = (rsi_ant >= rsi_sma_ant) and (rsi < rsi_sma)
        cruzou_acima  = (rsi_ant <= rsi_sma_ant) and (rsi > rsi_sma)

        if self._state == _NEUTRO:
            if rsi > self.rsi_ob:
                self._state = _SHORT_S1;  self._ref_high = high
            elif rsi < self.rsi_os:
                self._state = _LONG_S1;   self._ref_low = low

        elif self._state == _SHORT_S1:
            self._lookback_count += 1
            if self._lookback_count > self.lookback_limit:
                self._state = _NEUTRO
            elif high > self._ref_high:
                if rsi > self.rsi_ob:
                    self._ref_high = high          # renovação: ainda sobrecomprado
                else:
                    self._state = _SHORT_S2        # divergência RSI confirmada
                    if cruzou_abaixo:              # S2 e S3 na mesma vela
                        sl = high * (1 + self.sl_pct / 100)
                        self.sl_pendente = sl;  self._state = _NEUTRO
                        return 'VENDER'

        elif self._state == _SHORT_S2:
            self._lookback_count += 1
            if self._lookback_count > self.lookback_limit:
                self._state = _NEUTRO
            elif cruzou_abaixo:
                sl = high * (1 + self.sl_pct / 100)
                self.sl_pendente = sl;  self._state = _NEUTRO
                return 'VENDER'

        elif self._state == _LONG_S1:
            self._lookback_count += 1
            if self._lookback_count > self.lookback_limit:
                self._state = _NEUTRO
            elif low < self._ref_low:
                if rsi < self.rsi_os:
                    self._ref_low = low            # renovação: ainda sobrevendido
                else:
                    self._state = _LONG_S2         # divergência RSI confirmada
                    if cruzou_acima:
                        sl = low * (1 - self.sl_pct / 100)
                        self.sl_pendente = sl;  self._state = _NEUTRO
                        return 'COMPRAR'

        elif self._state == _LONG_S2:
            self._lookback_count += 1
            if self._lookback_count > self.lookback_limit:
                self._state = _NEUTRO
            elif cruzou_acima:
                sl = low * (1 - self.sl_pct / 100)
                self.sl_pendente = sl;  self._state = _NEUTRO
                return 'COMPRAR'

        return None

Os métodos abrir_posicao(), verificar_sl_tp() e fechar_posicao() estão no repositório completo. A lógica de SL e TP é padrão - o que diferencia esta implementação é exclusivamente o processar_vela() acima.

48 combinações, uma vencedora: como rodamos o grid search

O arquivo optimizador.py baixa os dados uma única vez e testa 48 combinações no mesmo conjunto de velas: quatro pares de OB/OS (70/30, 67/33, 65/35, 60/40) × três valores de SL (0,75%, 1,0%, 1,5%) × quatro multiplicadores de TP (1R, 1,5R, 2R, 3R).

O critério de seleção principal é o Profit Factor, não o retorno bruto isolado.

comparação 3 configurações backtesting RSI divergência
Grid search de 48 combinações: as 3 melhores configurações para ETH/USDT 4H

Segundo testes próprios do CriptoMatiko em julho/2026 (ETH/USDT:USDT Bybit Futures, 4H, dados CCXT + Python 3.12), a Config B com OB/OS=67/33, SL=1,5% e TP=2R registrou 119 operações, WR de 46,2%, Profit Factor de 1,64 e Sharpe de 0,99 - o maior Sharpe de todo o grid search de backtesting Python.

Repositório GitHub: como usar o código

O repositório github.com/VernonCM/bot-rsi-divergencia-bybit contém os seis arquivos completos. Para rodar o backtesting Python localmente, o processo segue o mesmo padrão que detalhamos em como usar a API Bybit com Python:

git clone https://github.com/VernonCM/bot-rsi-divergencia-bybit.git
cd bot-rsi-divergencia-bybit
pip install ccxt pandas numpy matplotlib

Crie um arquivo .env na raiz do projeto com suas chaves de API da Bybit. O .gitignore já está configurado para ignorar o .env - as chaves nunca são enviadas ao repositório por acidente.

Para rodar apenas o backtesting Python, as chaves não são necessárias: os dados históricos são baixados publicamente via CCXT.

Usamos o Claude Code para construir o backtester em uma tarde: a IA gerou a estrutura dos arquivos e os primeiros testes de validação, enquanto nossa equipe revisou a lógica da máquina de estados linha a linha.

BYBITAté $100

Abra sua conta na Bybit e receba até $100 USDT em bônus de boas-vindas

Mais de 80% dos novos usuários atingem esse nível via link CriptoMatiko

  • US$50 de bônus ao depositar $500 e negociar US$100 mil em volume
  • US$100 de bônus ao depositar $3.000 e negociar US$250 mil em volume
  • Exchange disponível para brasileiros — conta em português
Criar conta na Bybit →

Bônus sujeito a volume de negociação. Futuros indisponível para residentes BR.

Perguntas frequentes sobre divergência RSI

As perguntas abaixo reúnem as dúvidas mais comuns sobre divergência RSI em cripto, baseadas em buscas reais em PT-BR.

A divergência de RSI funciona em cripto?

Sim, com limitações. Em testes com ETH/USDT 4H de 2021 a 2026, a divergência RSI gerou +282% com Sharpe 0,99 enquanto o Buy & Hold do ETH retornou -8,7% no mesmo período.

A estratégia funciona melhor em ativos com tendências definidas e episódios claros de sobrecompra sobrevenda RSI - e perde eficiência em mercados laterais prolongados.

Qual o melhor timeframe para divergência RSI?

O 4H mostrou o melhor equilíbrio nos testes: gera sinais suficientes (119 operações em cinco anos) sem o excesso de ruído do 1H. O gráfico diário gera poucos sinais para validação estatística robusta.

Para quem está aprendendo como usar o indicador RSI como usar em automação, o 4H é o ponto de partida mais equilibrado - frequência suficiente sem overtrading.

Como identificar divergência RSI no gráfico?

Numa divergência de topo: o preço faz um novo máximo e o RSI registra um máximo menor que o anterior. Para visualizar no TradingView, adicione o indicador RSI como funciona com período 14 e trace linhas conectando os máximos do preço e os máximos correspondentes do RSI.

Se o preço sobe e o RSI desce, a divergência RSI bearish está configurada - aguarda o cruzamento abaixo da SMA(5) para confirmar o sinal.

Qual a diferença entre divergência altista e baixista no RSI?

A divergência altista (bullish) ocorre quando o preço faz uma nova mínima mas o RSI registra uma mínima menos extrema - sinal de esgotamento da pressão vendedora.

A divergência baixista (bearish) é o oposto: novo máximo no preço com máximo menor no RSI, indicando enfraquecimento do momentum de compra. Ambas seguem a mesma lógica de desconexão entre preço e indicador RSI.

Por que usar RSI 67/33 em vez de 70/30 para divergências?

Os limiares 67/33 geram mais episódios de sobrecompra sobrevenda RSI do que os convencionais 70/30 - e mais episódios significa mais candidatos a divergência RSI por período.

No grid search de 48 combinações para ETH/USDT 4H, as configurações com OB/OS=67/33 tiveram Profit Factor e Sharpe superiores às configurações com 70/30 no mesmo par e timeframe testados.

Vale a pena operar divergência RSI em cripto?

O backtest de cinco anos mostra resultados favoráveis - mas há contexto que os números não revelam sozinhos. A estratégia de divergência RSI tem WR de 46,2%, o que significa que mais da metade das operações fecha no stop loss.

Quem não entende isso antes de colocar o bot em produção vai abandonar a estratégia nos momentos de perda, justamente quando o sistema estatístico ainda é válido.

A frequência baixa de sinais - média de dois trades por mês em cinco anos - é uma vantagem para quem opera com disciplina, mas não serve para quem busca operação contínua. A divergência RSI é uma estratégia de paciência, não de volume.

Vernon

💡 Dica do Vernon: Se fosse recomendar um ponto de partida, começaria pela versão Pine Script no TradingView - sem risco de capital, visualização imediata dos sinais de divergência RSI no gráfico ao vivo. Só depois, quando a lógica fizer sentido visual, migraria para o backtesting Python. Esse é o caminho que percorremos: Pine Script primeiro, código depois.

⚠️ Aviso de risco: Trading de criptomoedas envolve risco real de perda de capital. Resultados passados não garantem resultados futuros. Este conteúdo é educacional e não constitui conselho financeiro ou de investimento.

O terceiro artigo da série fecha o trio: testamos o indicador MACD com filtro EMA200 no mesmo ETH/USDT 4H. Um perfil diferente - taxa de acerto de 32,7%, mas risco/retorno 1:3 entregou +148,4% com drawdown de apenas -19,7%.

Alguns links neste artigo são de afiliados, com bônus exclusivos para você. Como isso funciona?

Posts Similares