历史回放
全深度流推送的每个事件也会写进按小时的归档。拉一个小时,用消费实时连接的同一套代码回放它,就是一次回测。免费,无需密钥。
https://replay.shrine.trade/pump/YYYY/MM/DD/HH.jsonl.zst
小时为 UTC。文件在该小时结束后几分钟出现,归档从开启当天开始;更早的小时不存在。
浏览存储桶
归档放在一个公开的 Cloudflare R2 存储桶里。对象存储没有目录列表,所以存储桶自己维护一份:https://replay.shrine.trade/pump/index.json 列出它持有的每个小时,最早的在前,每次上传后重写。
{ "base": "https://replay.shrine.trade/pump", "pattern": "<base>/<hour>.jsonl.zst", "count": 312, "hours": ["2026/09/11/07", "2026/09/11/08", "…"] }
把 base、hours 里的一项和 .jsonl.zst 拼起来就是文件地址。要全部拉取就遍历 hours;要补缺口就找缺少的那一项。
格式
每行一个 JSON 对象,zstd 压缩。每一行就是实时 stream 事件,多一个字段:localTimestamp,我们的服务器看到该交易的毫秒时间,实时流里没有。其他一切,signature、block、timestamp、action、protocol、mint、breakdown、tradersInvolved、储备和发射权限,都如流页面所述。
一个小时压缩后几百 MB,解压后几 GB。请流式读取,不要整个载入。
直接复制
- JavaScript
- Python
- Shell
// Node 22.15+ 的 zlib 自带 zstd。更老的 Node:npm install fzstd。
import { createZstdDecompress } from "node:zlib";
import { createInterface } from "node:readline";
import { Readable } from "node:stream";
const url = "https://replay.shrine.trade/pump/2026/09/11/07.jsonl.zst";
const res = await fetch(url);
const lines = createInterface({ input: Readable.fromWeb(res.body).pipe(createZstdDecompress()) });
let buys = 0;
for await (const line of lines) {
const e = JSON.parse(line);
if (e.action === "buy" && e.protocol === "PUMPFUN") buys++;
}
console.log("pump.fun buys that hour:", buys);
import io, json, requests, zstandard # pip install zstandard requests
url = "https://replay.shrine.trade/pump/2026/09/11/07.jsonl.zst"
with requests.get(url, stream=True) as r:
reader = zstandard.ZstdDecompressor().stream_reader(r.raw)
buys = 0
for line in io.TextIOWrapper(reader, encoding="utf-8"):
e = json.loads(line)
if e["action"] == "buy" and e["protocol"] == "PUMPFUN":
buys += 1
print("pump.fun buys that hour:", buys)
curl -s https://replay.shrine.trade/pump/2026/09/11/07.jsonl.zst | zstd -d | head -3
说明
- 和实时一样的形状。 针对
subscribe_stream写的代码在归档上原样可用;喂给它行而不是 socket 事件。 - 尽早过滤。 每个发射台的每一笔交易都在里面。流式读取时只留你关心的协议和动作,其余丢掉。
- 顺序。 行按观察到的顺序排列,即区块顺序,偶有相邻互换。需要严格时按
block再按signature排序。 - 缺口。 采集器重启可能丢掉一小时内的一两分钟。没有标记;需要知道时比较
block号。