04 リアルタイム集計
インクリメンタルな materialized view が維持する 1 分足のクォート中間値 OHLC を読み出します。
macOS terminal: Run workshop commands in Terminal using zsh or bash.
開始条件
collector が healthy で、polymarket.price_ticks に行が入っています。
なぜ
ダッシュボードの利用者は同じ 1 分足の系列を何度も要求します。新しいブロックが届くたびに一度だけ 計算しておけば、ダッシュボードの更新ごとの処理が挿入時に移ります。アドホックな問いのために生の テーブルもそのまま使えます。
ステップ 1 — 集計ステートを正しくクエリする
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 はビューが書き込んだものであり、クエリ側は対応する Merge 関数で
確定させます。open と close はイベント時刻と決定的なイベント ID を使うため、順序が入れ替わって
到着した場合や同一ミリ秒の同着でも一貫して決まります。
ステップ 2 — 生クエリと集計クエリの読み取り行数を比べる
生データでの等価なクエリを実行します:
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;SQL コンソールで、両方のクエリの read rows を比べてください。集計側は
AggregatingMergeTree がバックグラウンドで結合するブロック単位のステートを読むため、通常は
ソースの更新をすべてスキャンするよりはるかに少ない行数で済みます。
ステップ 3 — ビューが挿入駆動であることを確認する
SELECT
max(minute) AS newest_minute,
dateDiff('second', newest_minute, now()) AS age_seconds,
countMerge(updates) AS source_updates
FROM polymarket.market_midpoints_1m;live または fixture モードでは、スケジュールされたリフレッシュ ジョブなしに newest_minute が
進みます。
完了条件
- 集計クエリが OHLC の行を返す;
- open/high/low/close が 0 から 100 の間の確率になっている; および
- フィードがアクティブな場合、
newest_minuteが現在時刻に追随している。
次: 市場の値動きを調査する。