跳到主要内容

历史回放

全深度流推送的每个事件也会写进按小时的归档。拉一个小时,用消费实时连接的同一套代码回放它,就是一次回测。免费,无需密钥。

https://replay.shrine.trade/pump/YYYY/MM/DD/HH.jsonl.zst

不需要脚本。把某个小时的地址粘贴到浏览器或下载工具里就能拿到文件:

https://replay.shrine.trade/pump/2026/09/14/12.jsonl.zst

这是 2026 年 9 月 14 日 UTC 12:00 到 13:00。用任意 zstd 工具解压(zstd -d、7-Zip 或 zstandard 包),逐行读取即可。要知道有哪些小时,打开 /pump/index.json。

小时为 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。请流式读取,不要整个载入。

直接复制​

// 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);

说明​

  • 和实时一样的形状。 针对 subscribe_stream 写的代码在归档上原样可用;喂给它行而不是 socket 事件。
  • 尽早过滤。 每个发射台的每一笔交易都在里面。流式读取时只留你关心的协议和动作,其余丢掉。
  • 顺序。 行按观察到的顺序排列,即区块顺序,偶有相邻互换。需要严格时按 block 再按 signature 排序。
  • 缺口。 采集器重启可能丢掉一小时内的一两分钟。没有标记;需要知道时比较 block 号。