04 Agregações em tempo real
Leia o OHLC do midpoint das cotações por minuto mantido por uma materialized view incremental.
Ponto de partida
O coletor está saudável e polymarket.price_ticks contém linhas.
Por quê
Usuários do dashboard solicitam repetidamente a mesma série por minuto. Calculá-la uma vez, à medida que novos blocos chegam, move o trabalho de cada atualização do dashboard para o momento da inserção. A tabela bruta continua disponível para perguntas ad hoc.
Etapa 1 — Consultar corretamente os estados agregados
SELECT
minute,
token_id,
round(argMinMerge(open) * 100, 2) AS open_percent,
round(maxMerge(high) * 100, 2) AS high_percent,
round(minMerge(low) * 100, 2) AS low_percent,
round(argMaxMerge(close) * 100, 2) AS close_percent,
countMerge(updates) AS updates
FROM polymarket.market_midpoints_1m
WHERE minute >= now() - INTERVAL 30 MINUTE
GROUP BY minute, token_id
ORDER BY minute DESC, token_id
LIMIT 30;argMinState/argMaxState foram gravados pela view; a consulta os finaliza com as funções Merge
correspondentes. Abertura e fechamento usam o horário do evento mais o ID determinístico, portanto
chegadas fora de ordem e empates no mesmo milissegundo são resolvidos de forma consistente.
Etapa 2 — Comparar as linhas lidas pelas consultas bruta e agregada
Execute o equivalente bruto:
SELECT
toStartOfMinute(event_at) AS minute,
token_id,
round(argMin(midpoint, tuple(event_at, event_id)) * 100, 2) AS open_percent,
round(max(midpoint) * 100, 2) AS high_percent,
round(min(midpoint) * 100, 2) AS low_percent,
round(argMax(midpoint, tuple(event_at, event_id)) * 100, 2) AS close_percent,
count() AS updates
FROM polymarket.price_ticks
WHERE midpoint > 0
AND event_at >= now() - INTERVAL 30 MINUTE
AND event_kind IN ('book_snapshot', 'price_change', 'best_bid_ask', 'rest_book')
GROUP BY minute, token_id
ORDER BY minute DESC, token_id
LIMIT 30;No SQL Console, compare as linhas lidas pelas duas consultas. A agregação lê estados no nível
do bloco, combinados em segundo plano pelo AggregatingMergeTree, normalmente muito menos linhas
do que a leitura de cada atualização da origem.
Etapa 3 — Confirmar que a view é acionada por inserções
SELECT
max(minute) AS newest_minute,
dateDiff('second', newest_minute, now()) AS age_seconds,
countMerge(updates) AS source_updates
FROM polymarket.market_midpoints_1m;Nos modos ao vivo ou fixture, newest_minute avança sem um job agendado de atualização.
Concluído quando
- a consulta agregada retornar linhas OHLC;
- abertura/máxima/mínima/fechamento forem probabilidades entre 0 e 100; e
newest_minuteestiver atual para um feed ativo.
Próximo: investigar um movimento do mercado.