用 Node.js 和 TypeScript 配合 Narwhal,可以获取节假日、发布日期、经济数据、大宗商品现货价格、汇率和预测市场赔率。直接用原生 fetch 加上你的 API 密钥,再用 cron 或主机上的定时任务运行脚本。
你将完成的设置
Node.js 为调用 Narwhal REST API 并读取 JSON 响应的脚本提供 JavaScript 运行环境。你会得到一个 ES 模块,带有共用的请求辅助函数,以及对全部六个数据领域的调用。Narwhal 用一个账户、一个 API 密钥覆盖全部数据 API,REST 与 MCP 共用该密钥。这里的脚本使用 REST,密钥从环境变量读取。
设置你的 API 密钥
- 创建免费密钥 在 注册页面 获取免费 API 密钥。这个脚本中每个数据领域的请求都用同一个密钥认证。
- 把密钥存入环境文件 把密钥以
NARWHAL_API_KEY为名放进.env文件。把YOUR_KEY换成你的密钥;脚本通过process.env.NARWHAL_API_KEY读取该值。NARWHAL_API_KEY=YOUR_KEY - 使用 ES 模块和匹配的 Node 版本 把脚本保存为
pull.mjs。Node 18.17 及更高版本自带全局fetch,因此 REST 调用不需要任何包。用node --env-file=.env pull.mjs加载.env文件则需要 Node 20.6 或更高版本。
请求头是 Authorization: Bearer YOUR_KEY。在脚本中,请求头的值取自环境变量,基础 URL 仍是 https://api.narwhalapi.com。每次调用都通过共用的辅助函数使用同一个请求头。
用代码获取数据
把这段代码保存到 pull.mjs。get 辅助函数根据基础 URL 和路径构建 URL,附上传入的查询参数,并用 fetch 发送 GET 请求。如果响应不成功,它会抛出包含状态和响应文本的错误;否则返回 JSON 响应,供调用方读取。
辅助函数和各领域的调用放在同一个 ES 模块里,并在发起请求之前先定义基础 URL 和请求头。参数对象属于每次调用:日历调用提供国家和日期过滤条件,CPI 调用提供起始期间,FX 调用提供货币。
const API = "https://api.narwhalapi.com";
const headers = { Authorization: `Bearer ${process.env.NARWHAL_API_KEY}` };
async function get(path, params = {}) {
const url = new URL(API + path);
for (const [key, value] of Object.entries(params)) url.searchParams.set(key, value);
const res = await fetch(url, { headers });
if (!res.ok) throw new Error(`${res.status} ${await res.text()}`);
return res.json();
}
const { holidays } = await get("/v1/calendars/holidays/USA/2026");
const { releases } = await get("/v1/economics/calendar", {
countries: "USA",
start_date: "2026-11-01",
end_date: "2026-11-30",
limit: 100,
});
const { observations } = await get("/v1/economics/USA/cpi/observations", {
start: "2025-09",
});
const { price } = await get("/v1/commodities/spot/BRENT/USD");
const { rates } = await get("/v1/fx/rates/USD", { currencies: "EUR,IDR" });
const { meetings } = await get("/v1/predictions/policy-paths/federal-reserve");
console.log(holidays.length, holidays[0].name);
console.log(releases.length, observations.at(-1));
console.log(
"Brent",
price,
Object.fromEntries(rates.map((rate) => [rate.currency, rate.rate])),
);
console.log(meetings[0].resolves_at.slice(0, 10), meetings[0].p_hold);运行 node --env-file=.env pull.mjs 来加载密钥并调用 API。各个调用会提取输出语句所用的响应字段。对于汇率,脚本把返回的货币和汇率条目转成对象;对于预测响应,它读取会议日期和按兵不动概率。后面的各领域示例也使用同一个 get 辅助函数和请求头。
安排定时拉取
使用 cron 或主机上的定时任务。用 cron 时,命令里要包含环境文件的路径和 pull.mjs 的路径,这样定时运行的脚本才能通过 process.env.NARWHAL_API_KEY 拿到密钥。命令被定时运行时,--env-file 选项仍然需要 Node 20.6 或更高版本。
0 7 * * * node --env-file=/path/.env /path/pull.mjs把 /path/.env 和 /path/pull.mjs 换成你自己文件的路径。有关安排请求的更多内容,请见安排每日数据拉取。
在 Node.js 中使用节假日
请求 2026 年美国节假日并读取 holidays 数组。每个节假日都有 date 和 name;示例会打印数组长度和第一个节假日的名称。截至 2026 年 10 月 24 日,响应包含 2026 年的 11 个美国节假日。若要在自己的输出中使用日期,读取节假日条目的 date。name 字段提供与该日期对应的节假日名称。
const { holidays } = await get(
"/v1/calendars/holidays/USA/2026"
);
console.log(holidays.length, holidays[0].name);在 Node.js 中使用发布日期
请求 2026 年 11 月这段时间的美国经济日历并读取 releases。每个条目都有 at、period、topic 和 status,因此可以把发布日期与主题和期间一起读取。截至 2026 年 10 月 24 日,这个 2026 年 11 月的区间内有 31 次发布。日期过滤属于日历请求,而 period 字段属于每个发布条目。需要在输出中使用主题和状态时,从同一个条目读取即可。
const { releases } = await get("/v1/economics/calendar", {
countries: "USA", start_date: "2026-11-01", end_date: "2026-11-30", limit: 100
});
console.log(releases.length);在 Node.js 中使用经济数据
带上 start 参数请求美国 CPI 观测值并读取 observations。每条观测值都有 period 和 value;示例读取返回数组中的最后一项。截至 2026 年 10 月 24 日,2026-09 这一期的 CPI 数值为 336.940。Narwhal 的经济数据还包括通胀、GDP 和收益率。读取观测值时,请让期间与数值一起保留,这样输出就能说明该数值属于哪个 CPI 期间。请求的起始期间通过查询参数传入。
const { observations } = await get(
"/v1/economics/USA/cpi/observations", { start: "2025-09" }
);
console.log(observations.at(-1));在 Node.js 中使用大宗商品现货价格
请求以 USD 计价的 Brent,并读取响应字段 price。截至 2026 年 10 月 24 日,Brent 为每桶 116.8809 美元。现货代码例如有 XAU、XAG、XPT、XPD、XCU、BRENT 和 WTI。此示例在请求路径中使用 BRENT 和 USD。这里的代码从 JSON 响应中读取单个 price 字段。大宗商品代码和货币是传给共用请求辅助函数的 URL 的一部分。
const { price } = await get(
"/v1/commodities/spot/BRENT/USD"
);
console.log("Brent", price);在 Node.js 中使用汇率
以 USD 为基础请求 EUR 和 IDR,并读取 rates。每一项都有 currency 和 rate,小数形式的汇率是字符串。截至 2026 年 10 月 24 日,USD/EUR 为 0.89342,USD/IDR 为 18107.8。示例把每种货币作为对象属性,对应其返回的汇率。所请求的货币是查询参数,基础货币则在路径中。直接使用返回的数组时,请连同每个汇率一起读取货币字段。
const { rates } = await get(
"/v1/fx/rates/USD", { currencies: "EUR,IDR" }
);
console.log(Object.fromEntries(rates.map((rate) => [rate.currency, rate.rate])));在 Node.js 中使用预测市场赔率
请求美联储政策路径并读取 meetings。每场会议都有 resolves_at、p_cut、p_hold 和 p_hike。截至 2026 年 10 月 24 日,2026 年 10 月 28 日那场会议的按兵不动概率为 0.9188。示例把第一个会议条目的日期与其按兵不动概率一起打印。需要降息或加息概率时,使用会议条目中的 p_cut 或 p_hike。请让 resolves_at 与概率一起保留,以标明它描述的是哪场会议。
const { meetings } = await get(
"/v1/predictions/policy-paths/federal-reserve"
);
console.log(meetings[0].resolves_at.slice(0, 10), meetings[0].p_hold);需要 TypeScript 类型吗?
只为你读取的响应字段添加类型即可。以 FX 示例来说,响应的结构是 { rates: { currency: string; rate: string }[] }。小数值是字符串,所以在 TypeScript 结构中把 rate 声明为 string。
为什么 await 在顶层?
ES 模块允许使用顶层 await,示例正是靠它来等待每个 get 调用。请使用这里的 .mjs 扩展名,或为 JavaScript ES 模块设置 "type": "module"。
发布于。