Título original: 《Cálculo preciso de PnL na Polymarket: por que seus lucros e perdas podem estar totalmente errados》
Autor original: Leo, analista de criptomoedas
Tenho trabalhado com automação de negociações na Polymarket há seis meses, e o maior erro que cometi não foi uma estratégia falha, mas sim não conseguir calcular corretamente quanto ganhei ou perdi.
Não sou incompetente. O problema é que o cálculo de PnL do PM é uma verdadeira zona de perigo. Os números fornecidos pela API oficial estão incorretos, e o ranking exibido por sites de análise de terceiros também está errado. Você escreve seu próprio script para calcular? Provavelmente também está errado.
Quão grande é a discrepância? O terceiro colocado no ranking, kch123, calculou uma perda de 3,5 milhões de dólares usando um método errado, enquanto o lucro real foi de 11,4 milhões de dólares. Não é uma diferença de alguns pontos percentuais — é que o símbolo de lucro e perda está invertido.
Este artigo desmonta cada erro que cometi. Se você negocia, desenvolve ferramentas ou acompanha rankings, cedo ou tarde vai se deparar com isso.
A abordagem mais intuitiva: usar a interface /positions, somar o campo cashPnl (lucro/prejuízo em dinheiro).
Testando com os três endereços do top 15 do ranking:
swisstony: soma de cashPnl +$35 mil, ranking real +$5,6 milhões, diferença de 158 vezes
kch123: soma de cashPnl -$3,52 milhões, ranking real +$11,4 milhões, símbolo invertido
gmanas: soma de cashPnl -$2,64 milhões, ranking real +$5,02 milhões, símbolo invertido
Para esses três endereços, dois tiveram o símbolo de lucro/prejuízo invertido.
Razão: a API /positions retorna cashPnl sem incluir os lucros realizados que já foram liquidados. Quando uma posição vencedora é automaticamente resgatada em USDC, essa posição desaparece da resposta da API. O que fica são posições não liquidadas — geralmente com prejuízo flutuante.
Você acha que está calculando todo o lucro/prejuízo, mas na verdade só está considerando a parte não liquidada.
Nos dados JSONL de negociações há um campo makerPnl (lucro/prejuízo do maker), que parece ser para calcular PnL. Mas não confie nisso.
Percebi que, na análise de dados de market-making, a soma de makerPnl difere por uma ordem de grandeza do fluxo de caixa na cadeia. A multiplicidade exata varia conforme o cenário, mas a direção é sempre a mesma: a lógica interna do makerPnl não condiz com o fluxo real de USDC.
Por maior que seja a discrepância, a conclusão é a mesma: não use esse campo para calcular PnL.
Isso é contra a intuição.
Se um txHash (hash da transação) aparece várias vezes, a reação natural é: dados duplicados, remover.
Mas não faça isso. O CLOB ( livro de ordens on-chain) da PM pode combinar várias ordens de maker em uma única transação na cadeia, e múltiplas entradas com o mesmo txHash representam execuções reais distintas.
Antes, eu deduzia por txHash + ativo, e isso fez eu subestimar $133 na lado de compra. Na rede Polygon, verifiquei que um único txHash realmente corresponde a múltiplos eventos de transferência de USDC, cada um representando uma negociação real.
Conclusão: não deduza apenas por txHash. Para calcular PnL, some diretamente os dados brutos de /activity.
Na API /activity, usar offset para paginação? Se passar de 3000, dá erro 400. O documento não informa isso.
Todos os três endereços testados confirmaram: GET /activity?offset=3100 retorna HTTP 400, com a mensagem de erro “max historical activity offset of 3000 exceeded”. Usuários com dezenas de milhares de transações não conseguem passar de 3000.
Usar o parâmetro end (passando o timestamp da última entrada da página anterior - 1) para paginação por cursor não tem limite.
Depois de calcular o PnL de um endereço, ao comparar com o ranking, há uma pequena diferença.
Na maioria das vezes, essa diferença é inferior a $10 (devido à volatilidade do valor de mercado das posições). Mas, se a discrepância for maior, possíveis razões incluem: janela de agregação do ranking, atraso na atualização do cache ou múltiplas carteiras proxy vinculadas ao usuário.
Na prática, usando o método de fluxo de caixa, o PnL de um único endereço bate de frente com o valor retornado pela API lb-api. Se a sua diferença for grande, verifique se a paginação está completa (erro 4) e se está usando os campos corretos (erros 1-2).
Depois de testar várias abordagens, a mais confiável que validei é a soma direta dos dados brutos da API de fluxo de caixa. Sem usar campos pré-calculados, apenas somando as entradas e saídas de fundos a partir dos registros originais.
Fórmula:
PnL = SOMA (negociações onde side=SELL) + SOMA (REDEEM) + SOMA (MERGE) + SOMA (REBATAS_DO_MAKER) + SOMA (REWARD) - SOMA (negociações onde side=BUY) - SOMA (SPLIT) + valor de mercado das posições
· TRADE BUY: gastar USDC para comprar tokens (saída)
· TRADE SELL: vender tokens para recuperar USDC (entrada)
· REDEEM: resgatar USDC de posições vencedoras (entrada)
· SPLIT: cunhar tokens com USDC (saída)
· MERGE: fundir tokens de volta em USDC (entrada)
· REBATAS_DO_MAKER: reembolso do maker (entrada)
· REWARD: recompensas ou airdrops (entrada)
· Fonte de dados:
GET /activity?user=<endereço>&limit=500, paginar com end, somar por tipo após obter todos os registros.
· Valor de mercado das posições:
GET /positions?user=<endereço>, calcular size × preço atual.
· Validação cruzada:
Comparar o resultado com a API de ranking do Polymarket (lb-api.polymarket.com/profit?window=all&address=X). Diferença < $10 é aceitável. Discrepâncias vêm da volatilidade do valor de mercado.
Após calcular pelo método de fluxo de caixa, validar com a API do ranking:
swisstony: fluxo de caixa +$5,6 milhões, ranking +$5,6 milhões, diferença < $10
kch123: fluxo de caixa +$11,4 milhões, ranking +$11,4 milhões, diferença < $10
gmanas: fluxo de caixa +$5,02 milhões, ranking +$5,02 milhões, diferença < $10
As diferenças entre os três endereços estão dentro de $10, sendo causadas pela volatilidade do valor de mercado.
Depois de validar o método, apliquei-o para analisar os lucros e perdas de centenas de endereços de destaque. E aí, a história mudou completamente.
SOMA(cashPnl) de /positions → não funciona, não inclui lucros realizados, pode inverter sinais
Soma do campo makerPnl → não funciona, não condiz com o fluxo de caixa na cadeia
Calculado deduzindo por txHash → não funciona, perde negociações reais acima de $100
Paginação com offset + soma → não funciona, dados truncados, erro > 3000
Método de fluxo de caixa na API → atualmente o mais confiável, < $10 de diferença
Para quem faz quant, o primeiro passo não é encontrar alpha. É garantir que seus cálculos estão corretos.
Tudo acima vem de experiências reais, não de teoria. A API do PM pode mudar a qualquer momento, por isso recomenda-se validar periodicamente com o ranking.
Link original
Clique para conhecer as vagas na BlockBeats
Participe do grupo oficial da BlockBeats no Telegram:
Telegram assinatura: https://t.me/theblockbeats
Telegram grupo de discussão: https://t.me/BlockBeats_App
Conta oficial no Twitter: https://twitter.com/BlockBeatsAsia
Related Articles
Os volumes vitalícios combinados da Polymarket e da Kalshi ultrapassam 150 mil milhões de dólares em abril
A16z apoia a CFTC numa carta de comentários de sexta-feira, citando as regras dos mercados de previsão estaduais como barreira de acesso
O volume de transacções acumulado da Polymarket e da Kalshi atinge 150 mil milhões de dólares: 21,9 mil milhões em Abril, novo máximo mensal
A16z apoia a CFTC e alerta que as regras de mercados de previsão ao nível dos estados criam barreiras de acesso ao mercado
Polymarket e Kalshi atingem $150B em volume vitalício combinado em abril
Os ETFs de Ethereum registam $184M mais de 4 dias de sequência negativa