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

Última atualização: 09/07/2026

Esta data marca uma revisão completa do conteúdo, não uma edição menor. Atualizamos preços, dados e informações da plataforma sempre que mudam de forma relevante.

✓ Verificado pelo nosso editorial

  • Dados verificados com fontes oficiais
  • Testado em conta real quando aplicável
  • Atualizado quando o produto muda

ⓘ Divulgação de afiliados

Alguns links deste artigo são de afiliados, com bônus exclusivos para você. Isso não influencia nossa avaliação. Como isso funciona?

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 Autor: 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 Autor: 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 depósito mínimo e volume de negociação.

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.

Divergência RSI não é o único indicador desta série que testamos com o mesmo rigor: o volume profile passou pelo mesmo processo de backtest e teve resultado bem diferente.

Vernon

💡 Dica do Autor: 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 testou 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%.

O quarto artigo fecha a série com uma abordagem completamente diferente: bandas de bollinger em mean reversion, em vez de seguir tendência. Com SL=1%, a configuração de referência gerou +22,7% no mesmo ETH/USDT 4H, com drawdown de apenas -1,0% - o menor drawdown de toda a série.

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

Posts Similares