文档

有了 API key 之后,三条命令就能把文件下到本地。下面第一段可以直接复制运行。

outcometick 是什么:Polymarket 与 Predict.fun 加密涨跌市场的 Chainlink 结算价流与盘口,以及 Polymarket 的成交流——持续采集,逐文件校验,通过 API 下载。已归档 158 个完整 UTC 日(自 2026-06-08 起;Predict.fun 自 2026-06-13 起)。Polymarket 7 个币种,Predict.fun 3 个币种。单平台订阅 ¥65/月起。

定价 · Polymarket 免费样本 · Predict.fun 免费样本 · 在线回测

60 秒上手

把第 1 行的 key 换成你自己的(结账那一页显示过一次),其余原样粘进终端。

# 1. your key, from the page you saw right after paying
export OT_KEY="ck_a1b2c3d4e5f6.xxxxxxxxxxxxxxxxxxxxxxxx"

# 2. what can I get?
curl -s -H "Authorization: Bearer $OT_KEY" \
  https://outcometick.com/v1/meta

# 3. find a file — with no date filter you get the newest day your key reaches
curl -s -H "Authorization: Bearer $OT_KEY" \
  "https://outcometick.com/v1/files?asset=btc&dataset=prices"

# 4. download it — every file in that listing carries its own url
URL=$(curl -s -H "Authorization: Bearer $OT_KEY" \
  "https://outcometick.com/v1/files?asset=btc&dataset=prices" \
  | jq -er '.files[0].url')

curl -L -H "Authorization: Bearer $OT_KEY" "$URL" -o btc-prices.csv.gz

第 4 步的 -L 不能省:下载接口返回的是 302 跳转,指向对象存储上的短时效链接。文件直接从存储下发,不经过我们的服务器。

在 Python 里一行读入

pandas、DuckDB、wget 这类工具没法给 URL 加请求头,所以下载接口也接受 ?api_key=。注意:key 出现在 URL 里会进浏览器历史和代理日志,能用请求头的地方还是用请求头。

import pandas as pd, requests

KEY  = "ck_a1b2c3d4e5f6.xxxxxxxxxxxxxxxxxxxxxxxx"
auth = {"Authorization": f"Bearer {KEY}"}

r = requests.get("https://outcometick.com/v1/files", headers=auth,
                 params={"asset": "btc", "dataset": "prices"})

# the download endpoint also takes ?api_key=, for clients that cannot set a header.
# The URL no longer ends in .gz, so name the compression; full_accuracy_value is
# a 1e18 fixed-point integer wider than int64, so keep it as text.
df = pd.read_csv(r.json()["files"][0]["url"] + "?api_key=" + KEY,
                 compression="gzip", dtype={"full_accuracy_value": str})
print(df.head())

同一个 URL 在 polars 和 DuckDB 里也能直接读;JSONL 数据集(markets、盘口、成交)读法相同。代码里的参数不是摆设:少了它们 pandas 直接读不出文件,pandas 和 DuckDB 还会把 1e18 定点数和 76 位 token id 悄悄转成浮点数。

import duckdb, pandas as pd, polars as pl, requests

KEY  = "ck_a1b2c3d4e5f6.xxxxxxxxxxxxxxxxxxxxxxxx"
auth = {"Authorization": f"Bearer {KEY}"}

def newest(dataset):
    r = requests.get("https://outcometick.com/v1/files", headers=auth,
                     params={"venue": "polymarket", "asset": "btc", "dataset": dataset})
    return r.json()["files"][0]["url"] + "?api_key=" + KEY

# CSV — settlement prices, here; klines read the same way
prices = newest("prices")
pl.read_csv(prices)
# types= only for prices / twap30s / twap60s: it errors on a file without the column
duckdb.sql(f"SELECT * FROM read_csv('{prices}', types={{'full_accuracy_value': 'VARCHAR'}})").df()

# JSONL — markets, book, trades: ids and prices are strings, keep them that way
markets = newest("markets")
pd.read_json(markets, lines=True, compression="gzip", dtype=False)
pl.read_ndjson(markets)
duckdb.sql(f"SELECT * FROM read_json('{markets}')").df()

每个文件也有 Parquet 版:列文件时加 format=parquet。行完全相同、类型已经解析好,不用再写压缩和精度参数。

import duckdb, polars as pl, requests

KEY  = "ck_a1b2c3d4e5f6.xxxxxxxxxxxxxxxxxxxxxxxx"
auth = {"Authorization": f"Bearer {KEY}"}

# format=parquet lists the Parquet copy of each file: the same rows, already typed
r = requests.get("https://outcometick.com/v1/files", headers=auth, params={
    "venue": "polymarket", "asset": "btc", "dataset": "book", "format": "parquet"})
url = r.json()["files"][0]["url"] + "?api_key=" + KEY

pl.read_parquet(url)
duckdb.sql(f"SELECT * FROM read_parquet('{url}')").df()

要对比两个平台?format=parquet 时用 dataset=markets_unified,可以拿到每个 markets 文件的另一份副本,两个平台同一套列:一行一个市场,时间统一为毫秒,价格是精确十进制,结果直接写明,一条查询就能把 Polymarket 和 Predict.fun 放在一起读。列说明见字段文档页。

不想先把文件下下来?同一份归档可以在密闭沙箱里直接对策略重放,成交按当时真实的盘口深度撮合——见 策略 SDK 参考

在 AI 编程工具里用(MCP)

npm 包里带了一个 MCP 服务,Claude Code、Cursor 等支持 MCP 的工具可以直接查覆盖范围、列出并下载文件(自动校验 sha256)、给回测报价、在本地校验策略、查看你的回测任务;配上聪明钱 key(OT_SMART_KEY)还能下载聪明钱名单。它跑在你自己的电脑上,需要 Node 24,key 只写在本地配置里。它不会提交回测,因为提交要扣 credits。

# Claude Code — every key is optional; public tools work without any
claude mcp add outcometick \
  -e OT_KEY="ck_a1b2c3d4e5f6.xxxxxxxxxxxxxxxxxxxxxxxx" \
  -e OT_SMART_KEY="ck_f6e5d4c3b2a1.xxxxxxxxxxxxxxxxxxxxxxxx" \
  -e OT_BACKTEST_KEY="bt_a1b2c3d4e5f6.xxxxxxxxxxxxxxxxxxxxxxxx" \
  -- npx -y -p outcometick ot mcp

Cursor、Claude Desktop 等其他 MCP 客户端用同一个服务,写成 JSON 配置:

{
  "mcpServers": {
    "outcometick": {
      "command": "npx",
      "args": ["-y", "-p", "outcometick", "ot", "mcp"],
      "env": { "OT_KEY": "ck_a1b2c3d4e5f6.xxxxxxxxxxxxxxxxxxxxxxxx" }
    }
  }
}

也可以直接用远程服务 https://outcometick.com/v1/mcp,什么都不用装。在 claude.ai 或 ChatGPT 里把它添加为自定义连接器:会跳到 outcometick 的页面让你粘贴 key,连接器拿到的是一个 token,key 被吊销或过期后它随之失效。要查看或断开用你的 key 连接过的应用,打开 https://outcometick.com/connections。能自定义请求头的客户端也可以直接带上 key。远程版的 download_file 和 smart_download 返回一个短时有效的签名下载链接和 sha256,check_strategy 改为接收文件内容而不是目录。

# Remote: nothing to install. The key goes in a header…
claude mcp add --transport http outcometick https://outcometick.com/v1/mcp \
  --header "Authorization: Bearer ck_a1b2c3d4e5f6.xxxxxxxxxxxxxxxxxxxxxxxx"

# …or leave --header out and sign in with your keys in the browser (OAuth).
# Public tools only, no key: https://outcometick.com/v1/mcp/public

HTTP API 也有 OpenAPI 3.1 描述,方便代码生成和 AI 调用:https://outcometick.com/v1/openapi.json。会花钱或扣 credits 的操作标了 x-requires-human-confirmation。

常见任务

某一天、某个币、某个周期的盘口

所有筛选条件都可选。date 只要一天;要范围就用 from / to。下面的例子都不写死日期,而是从 /v1/meta 读——它返回的正是你这把 key 够得到的窗口。

# the newest day your key reaches
DAY=$(curl -s -H "Authorization: Bearer $OT_KEY" \
  https://outcometick.com/v1/meta | jq -r .lastDay)

# every BTC 5-minute order book for that day
curl -s -H "Authorization: Bearer $OT_KEY" \
  "https://outcometick.com/v1/files?date=$DAY&asset=btc&interval=5m&dataset=book"

5 分钟市场的全套数据:盘口 + 结算流

结算流(prices / twap30s / twap60s)是连续的,本身没有周期,所以 interval=5m 不含它们。加上 none 才能一次拿全——判定 5 分钟市场的输赢要用 twap60s,光有盘口不够。

DAY=$(curl -s -H "Authorization: Bearer $OT_KEY" \
  https://outcometick.com/v1/meta | jq -r .lastDay)

# everything a 5-minute market needs: the 5m slices AND the settlement streams
curl -s -H "Authorization: Bearer $OT_KEY" \
  "https://outcometick.com/v1/files?date=$DAY&asset=btc&interval=5m,none"

一整月的结算价,下完自动校验

每个文件都带 sha256,与归档 manifest 里的值一致。校验通过说明你拿到的与我们发布的完全一致,而不只是「传输没报错」。

#!/usr/bin/env bash
# a month of BTC settlement prices, downloaded and checksum-verified
set -euo pipefail
export OT_KEY="ck_a1b2c3d4e5f6.xxxxxxxxxxxxxxxxxxxxxxxx"

# 30 days back from the newest day you can reach, clamped to the oldest —
# one call covers at most 92 days, and your window may be shorter than either
read -r FROM TO < <(curl -s -H "Authorization: Bearer $OT_KEY" \
  https://outcometick.com/v1/meta \
  | jq -r '((.lastDay | strptime("%Y-%m-%d") | mktime) - 29*86400
            | strftime("%Y-%m-%d")) as $back
           | "\(if $back < .firstDay then .firstDay else $back end) \(.lastDay)"')

curl -s -H "Authorization: Bearer $OT_KEY" \
  "https://outcometick.com/v1/files?asset=btc&dataset=prices&from=$FROM&to=$TO" \
| jq -r '.files[] | "\(.url) \(.name) \(.sha256)"' \
| while read -r url name sha; do
    curl -sL -H "Authorization: Bearer $OT_KEY" "$url" -o "$name"
    echo "$sha  $name" | sha256sum -c -
  done

直接拼成一个 DataFrame

import pandas as pd, requests
from datetime import date, timedelta

KEY  = "ck_a1b2c3d4e5f6.xxxxxxxxxxxxxxxxxxxxxxxx"
BASE = "https://outcometick.com"
auth = {"Authorization": f"Bearer {KEY}"}

meta  = requests.get(f"{BASE}/v1/meta", headers=auth).json()
last  = date.fromisoformat(meta["lastDay"])
first = max(date.fromisoformat(meta["firstDay"]), last - timedelta(days=6))

# every 1-minute kline for BTC over the last week your key reaches
r = requests.get(f"{BASE}/v1/files", headers=auth, params={
    "asset": "btc", "dataset": "klines", "interval": "1m",
    "from": first.isoformat(), "to": last.isoformat(),
})
files = r.json()["files"]

df = pd.concat(
    pd.read_csv(f["url"] + "?api_key=" + KEY, compression="gzip") for f in files
).sort_values("ts_ms")
print(len(df), "rows")

参考

Polymarket 与 Predict.fun 数据下载接口文档全部筛选参数、两种返回结构,以及每个状态码到底是什么意思。
字段规格逐数据集、逐平台的列与字段。两个平台并不共用一套。
市场怎么判定输赢由哪条流决定结果,以及怎么自己重算一遍。
取消订阅在账单页输入付款邮箱,我们会发一个登录链接,登录后能看到你的订阅。取消在已付周期结束时生效,到期前 key 照常可用;换卡、下载发票也在那里。区间买断和稳定币付款是一次性的,不需要取消。

教程

手续费、排队位置与 markout在免费样本日上回放两个简单策略,看 taker 手续费、盘口深度和排队会让结果差多少。
用对结算价判输赢回测用错 Chainlink 价格流会判反多少个结果,以及结果最早在什么时候显现。