outcometick

Dados históricos de ticks da Polymarket e Predict.fun, além de cotações de backtest e status, via MCP

Documentação

outcometick

O SDK de estratégias TypeScript / JavaScript e a linha de comando ot para outcometick.com — dados em nível de tick para mercados de Alta/Baixa de criptomoedas da Polymarket e Predict.fun.

npm i -g outcometick

ot check .                                           # validate, free, no data
ot run . --data ./polymarket-data-samples            # replay locally
ot submit . --assets btc,eth --days 30               # send it to the queue
ot status <run_id>                                   # where it got to
ot fetch  <run_id>                                   # download the report

Mudança na versão 2.0: os backtests cobrem apenas os 35 dias arquivados mais recentes, e a janela avança conforme os dias são arquivados. Um --from antes da janela, ou --days mais longo que ela, é recusado com E_SCOPE antes que qualquer coisa seja enviada, e a mensagem nomeia a janela atual. Use --days <n> para os n dias mais recentes; as datas atuais estão em https://outcometick.com/v1/backtest/capacity?venue=polymarket.

Escrevendo uma estratégia

Totalmente tipado — ot inclui declarações .d.ts, então uma estratégia que passa na verificação de tipos é uma que a fila aceitará.

import { Strategy, Order, type Ctx, type Tick } from "outcometick";

export default class MeanReversion extends Strategy<{ entry_z: number; size: number }> {
  private entered = false;

  onMarketOpen() { this.entered = false; }

  onTick(ctx: Ctx<{ entry_z: number; size: number }>, tick: Tick): Order | null {
    const z = ctx.zscore(tick.value, { window: 180 });
    if (this.entered || Math.abs(z) < ctx.p.entry_z) return null;
    const side = z > 0 ? "DOWN" : "UP";
    const limit = ctx.book().best(side);
    if (limit === null) return null;
    this.entered = true;
    return new Order({ side, size: ctx.p.size, limit });
  }
}

JavaScript puro também funciona — o runtime é ESM sem etapa de build.

O objetivo do ot check

Ele executa o mesmo validador que a fila executa — o mesmo módulo, não uma cópia. Se passar localmente, não será rejeitado no envio. Isso só é verdade porque existe uma única implementação, e é por isso que o validador e os analisadores estáticos vêm neste pacote, em vez de serem reimplementados no lado do cliente.

O que ot run é e não é

É o mesmo mecanismo, o mesmo relatório e o mesmo formato de arquivo que a fila usa, contra uma cópia local do arquivo:

curl -L https://github.com/outcometick/polymarket-tick-data-samples/releases/latest/download/polymarket-data-samples.tar.gz | tar xz

Não é o sandbox. Localmente, sua estratégia roda como você, com suas permissões, na sua máquina — o que é aceitável, porque é o seu código. Em nossas máquinas, ela roda em um contêiner sem rede, sem sistema de arquivos gravável e com um orçamento rígido de CPU e tempo de relógio.

Testes

npm install && npm test

Requer python3 no PATH: um dos dois analisadores estáticos é escrito em Python, e a CLI o aciona da mesma forma que a API faz.

Baixando dados

A outra metade do pacote: um cliente para a assinatura de dados, em um import separado porque não tem relação com escrever uma estratégia.

import { DataClient, NO_VALUE } from "outcometick/data";

const ot = new DataClient();                    // key from OT_KEY

const meta = await ot.meta();                   // what can this key see?

const { files } = await ot.files({
  from: "2026-08-01", to: "2026-08-12",         // or date: "2026-08-12"
  asset: ["BTC", "ETH"],                        // the BASE symbol, not BTCUSD
  dataset: "prices",
  interval: ["5m", NO_VALUE],                   // "5m" alone EXCLUDES the
});                                             // period-less settlement streams

await ot.download(files[0], { saveTo: files[0].name });   // checksum verified

meta() informa as dimensões que esta chave pode realmente alcançar. Observe que intervals contém apenas durações reais — o sentinela none é informado separadamente sob filterTokens, então um chamador que cria um enum a partir dele ou analisa os valores como durações nunca encontra um token.

Os downloads são verificados por checksum: /v1/dl redireciona para o armazenamento com o sha256 em um cabeçalho, e o cliente segue esse redirecionamento por conta própria, para que o checksum não seja descartado.

Reconstruindo um livro de ofertas da Polymarket

book e price_change são armazenados em uma cadência de captura, então uma remoção pode cair entre dois quadros armazenados e deixar um nível obsoleto para trás. OrderBook aplica a regra de reconstrução documentada: snapshots substituem a escada de um token, mudanças definem tamanhos absolutos (0 remove), e níveis cruzados pelo melhor bid/ask mais recente (de best_bid_ask e de cada mudança) são descartados. Alimente-o com linhas dos três arquivos mesclados por recv_ms.

import { OrderBook } from "outcometick/data";

const book = new OrderBook();
for (const row of rows) book.apply(row);       // parsed objects or JSONL lines
book.ladder(tokenId);                           // { bids: [{ price, size }], asks: [...] }, best first
book.best(tokenId);                             // { bid, ask }

Isso remove todos os níveis que os melhores preços ultrapassaram, mas não pode restaurar o que os quadros descartados adicionaram ou redimensionaram: até o próximo snapshot, um nível, inclusive no topo, pode estar ausente ou carregar um tamanho antigo (best_bid_ask tem apenas preços). best() é o melhor nível da escada reconstruída, não o melhor bid/ask mais recente do mercado — leia linhas best_bid_ask para isso.

Histórico de negociações de dinheiro inteligente

Uma assinatura separada com sua própria chave: arquivos diários das negociações feitas pelos traders mais bem classificados da Polymarket.

const smart = new DataClient({ key: process.env.OT_SMART_KEY });
const { days } = await smart.smartDays();                  // newest first
const day = days.find((d) => d.lists.top100?.status === "published")?.day;
if (day) await smart.smartDownload(day, "top100", { saveTo: "top100.csv.zst" });  // verified

O que são as listas e o que cada coluna significa: https://outcometick.com/polymarket-smart-money-data

Servidor MCP

ot mcp é um servidor Model Context Protocol via stdio, para assistentes de codificação e agentes. Ele lê, precifica, valida e baixa; nunca envia um backtest, porque isso gasta créditos. Requer Node 24 ou mais recente.

{
  "mcpServers": {
    "outcometick": {
      "command": "npx",
      "args": ["-y", "outcometick", "mcp"],
      "env": {
        "OT_KEY": "<data subscription key, optional>",
        "OT_BACKTEST_KEY": "<backtest key, optional>"
      }
    }
  }
}

Claude Code: claude mcp add outcometick -e OT_KEY=<data key> -- npx -y outcometick mcp

FerramentaChaveO que faz
coveragenenhumaO que o arquivo contém por venue: ativos, conjuntos de dados, intervalo de dias
plansnenhumaPlanos de assinatura de dados e seus preços ao vivo
backtest_capacitynenhumaQuais dias podem ser testados agora e quão ocupada está a fila
backtest_quotenenhumaPrecificar um escopo de backtest em créditos sem enviá-lo
check_strategynenhumaValidar um diretório de estratégia com o validador da própria fila, localmente
metaOT_KEYA janela de datas e os valores de filtro que a chave de dados pode alcançar
list_filesOT_KEYPesquisar arquivos do arquivo que a chave de dados pode baixar
download_fileOT_KEYBaixar um arquivo e verificar seu sha256
backtest_runsOT_BACKTEST_KEYExecuções recentes sob a chave de backtest e o saldo de créditos
backtest_statusOT_BACKTEST_KEYStatus de uma execução, créditos e resumo do relatório

Escrevendo sua estratégia em Python? O SDK para isso é pip install outcometick. ot executa essas também — é a única CLI para ambas as linguagens.

Referência completa: https://outcometick.com/docs/sdk

Links