Anatomia do spread: por que DEX e CEX nunca vão rodar em perfeita sintonia
Se você acha que arbitragem entre DEX e CEX é uma "máquina de imprimir dinheiro" onde basta achar uma diferença de 2% e mover tokens pra lá e pra cá, prepare-se para o choque de realidade. O spread entre corretoras não é dinheiro grátis: é um prêmio de risco cobrado por iliquidez, slippage e latência de infraestrutura.
Numa CEX (como Binance, Bybit ou EXMON), o preço é formado no livro de ofertas (Limit Order Book). A liquidez ali é ultra dinâmica: os market makers ajustam a grade de ordens em microssegundos e os algoritmos recalculam o fair value em tempo real com base nos índices de futuros.
Já numa DEX (como Uniswap, Raydium ou PancakeSwap), o preço depende diretamente da curva matemática de uma pool de liquidez. Em um AMM v2 clássico (x · y = k), o preço só mexe quando uma transação bate fisicamente na pool. Se o preço do token X despencar 5% em um segundo na Binance por causa de uma grande ordem de venda, a pool da Uniswap vai continuar travada no preço antigo mais alto até que:
- A transação de um bot de arbitragem seja enviada para a rede.
- Essa transação passe pela fase de validação e seja incluída no bloco.
É justamente nessa janela temporal (de alguns segundos em redes rápidas até vários blocos na Ethereum) que o spread nasce.
Raio-X técnico: de onde vem o spread explorável manualmente?
Tentar fazer isso manualmente para competir com bots de HFT e MEV searchers rodando em nós RPC privados e pagando "gorjetas" para validadores via Flashbots para fazer backrunning no mesmo bloco é impossível. Os microspreads de 0,2% a 0,5% no ETH ou BTC são engolidos pelos algoritmos em questão de microssegundos.
Mas o trader manual caça um tipo de assimetria completamente diferente:
- Pumps e dumps impulsivos em altcoins mid-cap. Uma "baleia" entra numa pool na DEX e despeja US$ 50.000 em tokens. Em uma pool sem tanta profundidade, o preço derrete de 4% a 7% num piscar de olhos. Os bots da CEX não conseguem boletar essa queda instantaneamente porque o livro de ofertas na CEX está denso e o preço lá nem se mexeu.
- Congestionamento da rede e picos nas taxas de gás. No meio do caos no mercado, o mempool fica totalmente entupido. Os bots de MEV caem temporariamente ou começam a exigir taxas absurdas, fazendo com que os spreads na DEX fiquem abertos por 2 a 5 minutos.
- Listagens dessincronizadas e suspensão de saques/depósitos (Deposit/Withdrawal Halt). Uma CEX trava os depósitos ou saques de um token em determinada rede por causa de uma atualização de nó. A ponte de liquidez entre a DEX e a CEX é cortada na hora. A CEX vira um ecossistema isolado e o preço lá começa a rodar solto, descolando da DEX em até 15%.
Arquitetura do setup e alocação de capital
O erro clássico do iniciante: ver o spread na DEX, comprar na CEX, clicar em "Sacar para a carteira" e ficar 15 minutos esperando a rede confirmar a transação. Até as moedas baterem na carteira, o spread não só evaporou, como você ainda realiza um prejuízo garantido.
O trading manual de spread exige um posicionamento delta-neutro ou uma divisão prévia de saldo.
O modelo Split Balance (Divisão de Saldo)
Esqueça essa ideia de transferir fundos de uma plataforma para outra no meio da operação. As transferências são feitas muito antes de abrir a sessão.
O seu capital é dividido em duas partes iguais:

Com essa estrutura, você executa as ordens de forma simultânea:
- Se o token estiver cotado a US$ 1,10 na DEX e a US$ 1,00 na CEX: você vende ARB instantaneamente na DEX (embolsando US$ 1,10) e compra ARB na CEX (a US$ 1,00).
- Não há movimentação física de moedas. Você acabou de embolsar um delta de 10% (descontadas as taxas) em questão de 3 segundos.
- O rebalanceamento do capital entre a carteira e a CEX é feito depois, quando o mercado acalmar e as taxas da rede voltarem para o piso.
Matemática do Trade: Cálculo de Spread Líquido e Ponto de Equilíbrio
Bater os olhos na tela, ver aquela diferença simpática de 3% e já comemorar como lucro garantido é o caminho clássico para zerar a banca de quem está começando no arbitrage. O spread bruto (Gross Spread) não vale absolutamente nada. O que importa de verdade é o spread líquido (Net Spread), depois de descontar todas as taxas e mordidas de infraestrutura no meio do caminho.
Fórmula de Cálculo do Retorno Líquido
Net_Profit = (Psell · V) - (Pbuy · V) - FeeCEX - FeeDEX - Gas - Impact
Onde:
- Psell e Pbuy - preços reais de execução das ordens (nada de Mid-Price tirado do topo do site, mas sim preços médios ponderados considerando a profundidade do book).
- V - volume da operação em assets base ou stablecoins.
- FeeCEX - taxa de taker da corretora (geralmente entre 0.05% e 0.1%).
- FeeDEX - taxa do pool (0.01%, 0.05%, 0.3% ou 1%, dependendo do tier do pool).
- Gas - custo para incluir a transação no bloco, convertido para USD.
- Impact - o impacto do seu próprio volume no preço de dentro do pool AMM.
O Chefão da Fase – Price Impact nas DEXs
Se você vê 10.000 moedas a $1.00 cada no book de uma CEX, você leva exatamente a $1.00 por unidade (mais a taxa). Já numa DEX rodando a mecânica clássica de Produto Constante (x · y = k), cada token comprado sai mais caro que o anterior.
A fórmula de preço de saída para o token x trocado pelo token y num pool x · y = k é:
yout = (yreserve · xin · (1 - fee)) / (xreserve + xin · (1 - fee))
Se você taca uma ordem de $5.000 num pool com $100.000 de liquidez, você escorrega o preço do pool em cerca de 5%. Aquela sua gordurinha de 3% de spread líquido evapora na hora, virando 2% de prejuízo antes mesmo da sua transação bater no bloco.
Tabela do Spread Real por Volume de Operação (Pool de $50k, Spread Bruto de 2.5%)
| Volume do Trade ($) | Price Impact (%) | Taxas (Gas + Fees) | Spread Líquido (%) | Resultado do Trade |
|---|---|---|---|---|
| $100 | ~0.2% | ~$1.50 (1.5%) | +0.8% | Lucro troco de pão |
| $500 | ~1.0% | ~$1.50 (0.3%) | +1.2% | Lucro otimizado |
| $2,000 | ~3.8% | ~$1.50 (0.075%) | -1.375% | Loss por causa do Impact |
Resumo da ópera: todo pool tem um teto estritamente matemático de volume por trade. Tentar empurrar capital demais é pedir para quebrar a própria estratégia.
Automatizando o Garimpo: Criando um Monitor em Python
Ficar abrindo o browser e dando F5 em abas do DexScreener e no book da corretora na unha é coisa da pré-história. Quem faz arbitrage de verdade não usa código para executar trade de forma autônoma (tentar bater de frente com MEV bots é perda de tempo certa), mas sim para disparar um alerta sonoro ou de texto no Telegram/console no exato segundo em que uma janela anômala se abre.
Abaixo está um script 100% funcional e redondo em Python 3.10+. Ele monitora em tempo real as reservas diretas de um pool PancakeSwap v2 (BNB Chain) via RPC e cruza os dados com o orderbook de uma CEX (usando a REST API da Binance de exemplo, facilmente plugável em outras). O código é direto ao ponto e serve perfeitamente como base para evoluir.
Código do Scanner de Spread com Reservas e Taxas Embutidas
import sys
import time
import requests
from web3 import Web3
# ============================================================
# CONFIG
# ============================================================
BSC_RPC = "https://bsc-dataseed1.binance.org"
POOL_ADDRESS = Web3.to_checksum_address(
"0x16b9a82891338f9bA80E2D6970FddA79D1eb0daE"
)
BINANCE_DEPTH_URL = (
"https://api.binance.com/api/v3/depth"
"?symbol=BNBUSDT&limit=20"
)
TRADE_VOLUME_USD = 300.0
CEX_TAKER_FEE = 0.001
DEX_FEE = 0.0025
MIN_NET_SPREAD_PCT = 0.8
# custo estimado de gás por swap
ESTIMATED_GAS_COST_USD = 0.15
REQUEST_TIMEOUT = 3
# ============================================================
# WEB3
# ============================================================
w3 = Web3(Web3.HTTPProvider(BSC_RPC))
if not w3.is_connected():
print("Erro ao conectar no BSC RPC")
sys.exit(1)
# ============================================================
# ABI
# ============================================================
PAIR_ABI = [
{
"constant": True,
"inputs": [],
"name": "getReserves",
"outputs": [
{"name": "_reserve0", "type": "uint112"},
{"name": "_reserve1", "type": "uint112"},
{"name": "_blockTimestampLast", "type": "uint32"},
],
"stateMutability": "view",
"type": "function",
},
{
"constant": True,
"inputs": [],
"name": "token0",
"outputs": [{"name": "", "type": "address"}],
"stateMutability": "view",
"type": "function",
},
{
"constant": True,
"inputs": [],
"name": "token1",
"outputs": [{"name": "", "type": "address"}],
"stateMutability": "view",
"type": "function",
},
]
pair = w3.eth.contract(
address=POOL_ADDRESS,
abi=PAIR_ABI
)
# ============================================================
# KNOWN TOKENS
# ============================================================
WBNB = Web3.to_checksum_address(
"0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c"
)
USDT = Web3.to_checksum_address(
"0x55d398326f99059fF775485246999027B3197955"
)
# ============================================================
# VERIFY PAIR
# ============================================================
try:
token0 = Web3.to_checksum_address(
pair.functions.token0().call()
)
token1 = Web3.to_checksum_address(
pair.functions.token1().call()
)
except Exception as e:
print("Erro ao ler token0/token1")
print(e)
sys.exit(1)
PAIR_LAYOUT = None
if token0 == WBNB and token1 == USDT:
PAIR_LAYOUT = "WBNB_USDT"
elif token0 == USDT and token1 == WBNB:
PAIR_LAYOUT = "USDT_WBNB"
else:
print("Pool não é um par WBNB/USDT válido")
print("token0 =", token0)
print("token1 =", token1)
sys.exit(1)
print("Pair verified:")
print("token0 =", token0)
print("token1 =", token1)
# ============================================================
# BINANCE
# ============================================================
def get_orderbook():
try:
response = requests.get(
BINANCE_DEPTH_URL,
timeout=REQUEST_TIMEOUT
)
response.raise_for_status()
data = response.json()
if "bids" not in data:
return None
if "asks" not in data:
return None
return data
except Exception:
return None
def calculate_execution_buy_price(
asks,
target_usd
):
"""
Compra de BNB com USDT.
Retorna:
avg_price,
received_bnb
"""
spent_usd = 0.0
received_bnb = 0.0
for price_str, qty_str in asks:
price = float(price_str)
qty = float(qty_str)
level_usd = price * qty
if spent_usd + level_usd >= target_usd:
remaining_usd = target_usd - spent_usd
partial_qty = remaining_usd / price
received_bnb += partial_qty
spent_usd += remaining_usd
break
received_bnb += qty
spent_usd += level_usd
if spent_usd < target_usd:
return None, None
avg_price = spent_usd / received_bnb
return avg_price, received_bnb
def calculate_execution_sell_price(
bids,
sell_bnb
):
"""
Venda de BNB por USDT.
Retorna:
avg_price,
received_usdt
"""
remaining_bnb = sell_bnb
received_usdt = 0.0
sold_bnb = 0.0
for price_str, qty_str in bids:
price = float(price_str)
qty = float(qty_str)
take_qty = min(
remaining_bnb,
qty
)
received_usdt += take_qty * price
sold_bnb += take_qty
remaining_bnb -= take_qty
if remaining_bnb <= 0:
break
if remaining_bnb > 0:
return None, None
avg_price = received_usdt / sold_bnb
return avg_price, received_usdt
# ============================================================
# DEX
# ============================================================
def get_reserves():
try:
reserves = (
pair.functions
.getReserves()
.call()
)
raw0 = reserves[0]
raw1 = reserves[1]
if PAIR_LAYOUT == "WBNB_USDT":
reserve_bnb = raw0 / 1e18
reserve_usdt = raw1 / 1e18
else:
reserve_usdt = raw0 / 1e18
reserve_bnb = raw1 / 1e18
return (
reserve_bnb,
reserve_usdt
)
except Exception:
return None, None
def amm_out(
amount_in,
reserve_in,
reserve_out
):
if (
amount_in <= 0
or reserve_in <= 0
or reserve_out <= 0
):
return 0.0
amount_in_fee = (
amount_in
* (1 - DEX_FEE)
)
numerator = (
amount_in_fee
* reserve_out
)
denominator = (
reserve_in
+ amount_in_fee
)
return numerator / denominator
# ============================================================
# MONITOR
# ============================================================
def monitor():
print()
print("DEX/CEX Arbitrage Monitor Started")
print("-" * 80)
while True:
book = get_orderbook()
if book is None:
time.sleep(1)
continue
reserve_bnb, reserve_usdt = (
get_reserves()
)
if (
reserve_bnb is None
or reserve_usdt is None
):
time.sleep(1)
continue
bids = book["bids"]
asks = book["asks"]
# ====================================================
# SCENARIO A
# BUY ON DEX
# SELL ON CEX
# ====================================================
bnb_from_dex = amm_out(
TRADE_VOLUME_USD,
reserve_usdt,
reserve_bnb
)
if bnb_from_dex <= 0:
time.sleep(1)
continue
sell_price, usdt_received = (
calculate_execution_sell_price(
bids,
bnb_from_dex
)
)
if usdt_received is None:
time.sleep(1)
continue
usdt_received *= (
1 - CEX_TAKER_FEE
)
usdt_received -= (
ESTIMATED_GAS_COST_USD
)
spread_a = (
(usdt_received - TRADE_VOLUME_USD)
/ TRADE_VOLUME_USD
) * 100
# ====================================================
# SCENARIO B
# BUY ON CEX
# SELL ON DEX
# ====================================================
buy_price, bought_bnb = (
calculate_execution_buy_price(
asks,
TRADE_VOLUME_USD
)
)
if bought_bnb is None:
time.sleep(1)
continue
bought_bnb *= (
1 - CEX_TAKER_FEE
)
usdt_from_dex = amm_out(
bought_bnb,
reserve_bnb,
reserve_usdt
)
usdt_from_dex -= (
ESTIMATED_GAS_COST_USD
)
spread_b = (
(usdt_from_dex - TRADE_VOLUME_USD)
/ TRADE_VOLUME_USD
) * 100
dex_price = (
reserve_usdt
/ reserve_bnb
)
sys.stdout.write(
"\r"
f"DEX={dex_price:.2f} | "
f"A:{spread_a:+.2f}% | "
f"B:{spread_b:+.2f}%"
)
sys.stdout.flush()
if spread_a >= MIN_NET_SPREAD_PCT:
print(
"\n"
f"[SIGNAL] "
f"BUY DEX -> SELL CEX "
f"({spread_a:.2f}%)"
)
elif spread_b >= MIN_NET_SPREAD_PCT:
print(
"\n"
f"[SIGNAL] "
f"BUY CEX -> SELL DEX "
f"({spread_b:.2f}%)"
)
time.sleep(1.5)
# ============================================================
# ENTRY
# ============================================================
if __name__ == "__main__":
try:
monitor()
except KeyboardInterrupt:
print("\nStopped.")Esse script calcula o slippage real porque ele não cata a cotação pelo preço padrão de tabela, mas sim joga o seu volume exato de $300 direto na matemática interna do pool.
Protocolo de execução manual: como não virar presa fácil para os sandwich bots
Clicar em dois botões em exchanges diferentes parece tarefa simples. Na prática, 80% dos traders manuais acabam torrando o lucro no exato segundo em que mandam a transação pro mempool público.
Assim que a sua transação de compra na DEX bate no mempool público da Ethereum, BNB Chain ou Arbitrum, os MEV bots (Maximum Extractable Value) colam em cima na hora. Se o seu Slippage Tolerance (tolerância a derrapagem) estiver configurado acima de 0.5%, o bot tanca uma sandwich attack (ataque de sanduíche) rapidinho:
- O bot compra o token logo antes da sua transação, jogando o preço lá em cima (Frontrun).
- A sua transação é executada no pior preço possível, bem no talo do seu limite de slippage.
- O bot despeja o token logo depois de você e embolsa o lucro (Backrun).
O resultado? Você pega o token inflado e o spread inteiro vai parar no bolso do MEV searcher.
Pipeline de Execução Blindada
Para farmar os spreads na mão sem alimentar os bots, você precisa configurar a sua operação seguindo este esquema:
- Nodes RPC privados (MEV-Blocker / Flashbots). Esqueça as configurações de rede padrão da MetaMask. Qualquer transação em DEX deve sair exclusivamente por relays privados que jogam a transação direto pro validador do bloco, passando longe do mempool público.
Para Ethereum: https://rpc.mevblocker.io ou https://rpc.flashbots.net
Para BNB Chain / Polygon / Arbitrum: utilize os serviços de MEV-Protection da QuickNode ou ferramentas como a BloXroute. - Slippage Limit rígido. Nada de deixar aquele 1% ou 2% padrão nas interfaces da Uniswap ou 1inch. O slippage máximo aceitável para um trade de arbitragem fica entre 0.1% e 0.3%. Se o preço voar um milissegundo antes de entrar no bloco, a transação tem que dar revert por erro, e não ser executada no prejuízo.
- Otimização de Gas Fee. Jogue a configuração de taxa da sua carteira Web3 pro modo manual (Advanced Gas Controls). Defina a Max Priority Fee (gorjeta pro validador) um pouco acima da mediana atual da rede para garantir o seu lugar no topo do próximo bloco. Em redes L2 (Arbitrum, Base, OP), ficar de olho na L1 Data Fee é vital — quando a Ethereum tá congestionada, despachar transações na L2 pode custar até 5 vezes mais caro que o normal.
Técnica Avançada: Arbitragem Delta-Neutro «DEX Spot vs CEX Futures»
Segurar altcoin fisicamente nos dois saldos enquanto espera o spread aparecer é pedir pra tomar loss por desvalorização do ativo (Market Price Risk). Se as moedas derreterem 15%, o seu spread travado de 2% não vai cobrir o rombo no seu saldo.
A metodologia avançada utilizada na EXMON Academy é o spread trading delta-neutro via futuros.
Mecânica Operacional via Short Hedge
Em vez de comprar o ativo spot numa CEX, você segura uma posição vendida (short) em futuros com alavancagem de 1x lá dentro.

Algoritmo de execução:
- Rola um dump na DEX: o token despenca para $0.95, enquanto na CEX o futuro e o spot continuam firmes em $1.00 (spread de 5.2%).
- Você compra o spot na DEX a $0.95.
- Ao mesmo tempo, abre um Short no futuro na CEX a $1.00.
- O seu delta zera na hora: não importa para onde o mercado vá, o patrimônio total da sua banca fica intacto.
- Quando o preço na DEX emparelha com a CEX (digamos que ambas as plataformas estacionem em $0.98), você encerra as duas pontas:
- Vende o spot na DEX a $0.98 (Lucro: +$0.03 por moeda).
- Fecha o short na CEX a $0.98 (Lucro: +$0.02 por moeda).
Lucro líquido total: $0.05 por moeda (5% sobre o volume alocado) com risco zero de queda do token.
Bônus extra: Se o contrato futuro na CEX estiver operando em contango (preço do futuro acima do spot), você ainda fatura uma Funding Rate (taxa de financiamento) positiva a cada hora de apuração.
Armadilhas Ocultas e Riscos Críticos
Se uma estratégia parece perfeita demais, é porque você ainda não achou as brechas escondidas. O spread trading manual é um campo minado de engenharia.
1. Tokens com Taxa Embutida (Transfer Tax / Reflection Tokens)
Certos tokens ERC-20 / BEP-20 trazem uma taxa embutida direto no smart contract para cada transferência (como 2% a 5% destinados a burn ou carteira de marketing).
Se você não conferir o código do contrato num explorer ou scanner (TokenSniffer, GoPlus), vai puxar o token do pool, perder 5% de cara na mecânica do próprio token, mais 0.3% de taxa da AMM, e fechar a operação num prejuízo brutal.
2. Deslocamento de Liquidez Virtual na Uniswap v3 (Concentrated Liquidity Trap)
Na Uniswap v2, a liquidez fica espalhada de zero ao infinito. Na v3, ela se concentra em faixas estreitas de preço (Ticks).
Se o spread surgiu porque o preço escapou do range do formador de mercado principal, visualmente a diferença de preço pode parecer gigante (até 10% ou 20%). Só que o volume de liquidez naquele tick específico pode ser de meros $15. Tentar mandar uma ordem ali vai fazer o preço derrapar dezenas por cento contra você instantaneamente.
3. Desbalanceamento de Liquidez e Capital Preso (Inventory Risk)
Depois de farmar o spread 5 vezes seguidas para o mesmo lado (tipo: Compra na DEX -> Venda na CEX), você vai secar todo o seu USDT na CEX e entupir sua carteira Web3 de altcoins.
Fazer o rebalanceamento demanda tempo e gasta gás. Se o mercado engatar um super tendência, você vai ficar travado em uma perna só da operação. Regra de ouro de risco: nunca permita que o desequilíbrio de saldo entre as plataformas ultrapasse a proporção de 70/30.
Checklist do Trader antes do Clique
Cole essa checklist bem na frente do seu monitor de trabalho. Só entre na operação se os 5 requisitos forem atendidos:
- Proteção MEV ativada: Node RPC privado selecionado na carteira (MEV-Blocker / Flashbots).
- Profundidade do pool verificada: O volume da ordem não passa de 1% a 2% das reservas totais do pool na DEX (Price Impact < 0.3%).
- Spread limpo garantido: A diferença de preço cobre as taxas somadas de CEX + DEX + Gas por pelo menos 2.5 vezes.
- Smart contract limpo: O token não tem taxa de transferência oculta (Transfer Fee = 0%).
- Capital distribuído: Há saldo suficiente em ambas as moedas do par tanto na CEX quanto na DEX para uma execução imediata, sem precisar esperar pontes (bridges) transferirem fundos.
Fazer spread trading entre ambientes descentralizados e centralizados é pura disciplina matemática. Quem ganha aqui não é quem adivinha a direção da tendência, mas sim quem calcula melhor as taxas, domina a infraestrutura e sabe esperar pacientemente pela sua anomalia.