用 Python 接入数据(只需标准库)
第一步:拿一把免费 key。 注册后在「我的 API Key」里自助创建。 免费档就能取当前窗口的完整数据(含 2 秒序列),不付费。
一、最小可用客户端
import json, os, urllib.request, urllib.error, urllib.parse
BASE = "https://api.wanminguo.top/quant/polymarket/v1"
KEY = os.environ.get("PM_API_KEY", "")
class ApiError(Exception):
def __init__(self, status, code, message, body=None):
super().__init__(f"[{status}] {code}: {message}")
self.status, self.code, self.message, self.body = status, code, message, body
def call(path, **params):
"""调一个 /v1 端点。返回 (data, meta)。"""
if not KEY:
raise SystemExit("请先设置环境变量 PM_API_KEY(免费注册:"
"https://api.wanminguo.top/me/register.php)")
qs = "&".join(f"{k}={urllib.parse.quote(str(v))}" for k, v in params.items() if v is not None)
url = f"{BASE}/{path}" + (f"?{qs}" if qs else "")
req = urllib.request.Request(url, headers={"X-Api-Key": KEY,
"Accept": "application/json"})
try:
with urllib.request.urlopen(req, timeout=15) as r:
body = json.loads(r.read().decode("utf-8"))
except urllib.error.HTTPError as e:
try:
body = json.loads(e.read().decode("utf-8"))
except Exception:
body = {}
raise ApiError(e.code, body.get("error", "http_error"),
body.get("message", ""), body) from None
if not body.get("ok"):
raise ApiError(200, body.get("error", "unknown"), body.get("message", ""), body)
return body.get("data"), body.get("meta", {})
if __name__ == "__main__":
data, meta = call("window.php", market="eth")
print("窗口 :", data["slug"])
print("距 beat :", data["official_bp"], "bp →", data["leading_side"])
print("剩余 :", data["remaining"], "秒")
print("额度余额 :", meta["credits"]["balance"], "股(1 股 = 1 额度,成交才扣)")
二、响应信封(每次都要看的两处)
{
"ok": true,
"data": { ... },
"meta": {
"plan": "free",
"quota": { "mode": "subscription", "daily_limit": null,
"used_today": 0, "remaining": null, "reset_at": null },
"credits": { "balance": 10000, "total_in": 10000, "total_used": 0 },
"limits": { "qps": 20, "history_days": 1, ... },
"feed": { "ok": true, "latest_slug": "eth-updown-5m-...", "latest_age_sec": 3 },
"server_ts": 1790409000
}
}
meta.credits.balance—— 账号额度余额(股),成交 1 股扣 1 额度; 信号订阅制**无请求配额**(不再按请求数计费);meta.feed.latest_age_sec—— 采集器是否还在正常写数。 这个值持续变大说明数据流断了,此时拿到的「当前窗口」可能是旧的;- 错误时
ok=false且带error/message。
三、常用端点
路径(都带 .php) | 用途 | 关键参数 |
|---|---|---|
/v1/window.php | 当前/指定窗口快照 | market slug series=1 n |
/v1/settle.php | 结算核对 | market slug last |
/v1/history.php | 历史窗口列表 | market from to limit offset |
/v1/samples.php | 原始 2 秒样本(需套餐) | slug limit tail |
/v1/stats.php | 汇总统计(免费档可用) | — |
/v1/index.php | 端点清单与你的套餐限额 | — |
7 个市场的 ?market= 短名:btc eth sol
xrp doge hype bnb
(也接受 ETH-5m / eth-updown-5m 这种写法)。
⚠️ 路径必须带
.php —— 本站没有配置 URL rewrite,
写成 /v1/window 会 404。
四、429 要怎么处理
| 错误码 | 含义 | 正确做法 |
|---|---|---|
rate_limited | 同一秒请求过多(秒级防护,20 qps 上限) | 按响应头 Retry-After 退避 1 秒后重试即可 |
信号订阅制下**没有请求配额**(额度按成交股数扣),不再有 daily_quota_exceeded。
五、轮询频率建议
数据本身就是 约 2 秒一条,所以轮询窗口端点 1~2 秒一次就够了, 更密没有信息增益。订阅制下请求不限量,不用再计算"配额够不够撑多久"—— 只有**实际成交**才扣账号额度(1 股 = 1 额度)。
六、现成的完整示例
站上有一份客户端本体与四个示例,全部只用标准库,下载到同一目录即可运行:
https://api.wanminguo.top/quant/polymarket/examples/pm_api_client.py ← 客户端本体(可 import)
https://api.wanminguo.top/quant/polymarket/examples/current_window.py ← 当前窗口快照
https://api.wanminguo.top/quant/polymarket/examples/settle_recent.py ← 最近结算(--verify 本地复算四规则)
https://api.wanminguo.top/quant/polymarket/examples/history.py ← 历史窗口(自动翻页)
https://api.wanminguo.top/quant/polymarket/examples/samples.py ← 原始 2 秒样本
export PM_API_KEY=pm_live_xxxxxxxx
python current_window.py --market eth # 当前窗口
python settle_recent.py --last 10 --verify # 最近 10 个结算并本地复算
python history.py --from 2026-09-25 --limit 50 # 历史
python samples.py --slug eth-updown-5m-1790401800 --tail 1 # 原始样本
客户端把
beat_trusted、meta.credits、Retry-After
都当作一等公民处理 —— 尤其 beat_trusted=false 时会明确提示
「这个窗口不适合用来定方向」,不会静默吞掉。