你可以透過 Narwhal API 把國定假日、發布日期、經濟數據、大宗商品現貨價格、匯率和預測市場機率拉取到 Google 試算表。用 Apps Script 把資料寫入不同的工作表,再新增時間驅動的觸發條件,就能按排程重新整理。
你將完成的設定
Apps Script 透過 UrlFetchApp 把你的試算表連接到 API。你會得到每個資料領域各一個工作表,以及用同一把 API 金鑰填入它們的 pullAll 函式。金鑰儲存在腳本屬性中,腳本發出請求時讀取它。REST 和 MCP 在各個資料 API 中共用該金鑰。基礎 URL 為 https://api.narwhalapi.com,每個資料呼叫都使用 GET。
設定你的 API 金鑰
- 建立免費金鑰 取得一把免費的 Narwhal API 金鑰。請保留好這把金鑰,用於稍後在編輯器中新增的腳本屬性;切勿把它寫進試算表儲存格。
- 開啟 Apps Script 在 Google 試算表中開啟「擴充功能」選單,選擇 Apps Script。你將在這裡新增腳本,並設定它對金鑰的存取。
- 把金鑰存入腳本屬性 在「專案設定」中,新增一個名為
NARWHAL_API_KEY的腳本屬性,並把值設為你的金鑰。腳本透過PropertiesService.getScriptProperties()讀取它,並放在Authorization標頭中傳送,格式為Bearer YOUR_KEY。
用 Apps Script 取得資料
- 建立資料工作表 建立名為
Holidays、Releases、CPI、Brent、FX和Fed的工作表。腳本靠這些名稱找到每個回應的寫入位置,所以請完全按原樣命名。 - 新增腳本 把這段程式碼貼到 Apps Script 中。共用的
pull輔助函式會讀取每次呼叫指定的回應欄位,並把資料列寫入對應的工作表。Brent 的價格不在清單裡,所以直接使用回應物件。const API = "https://api.narwhalapi.com"; function pull(sheetName, path, listKey) { const key = PropertiesService.getScriptProperties().getProperty("NARWHAL_API_KEY"); const res = UrlFetchApp.fetch(API + path, { headers: { Authorization: "Bearer " + key }, }); const body = JSON.parse(res.getContentText()); const rows = listKey ? body[listKey] : [body]; if (!rows || rows.length === 0) return; // an empty list writes nothing const columns = []; rows.forEach((row) => Object.keys(row).forEach((name) => { // every row, so a null first value cannot hide a column if ( !columns.includes(name) && (row[name] === null || typeof row[name] !== "object") ) columns.push(name); }), ); const values = [columns].concat( rows.map((row) => columns.map((name) => row[name] === undefined || row[name] === null ? "" : row[name], ), ), ); const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(sheetName); sheet.clear(); // Text columns (dates, periods like 2026-09) stay plain text so Sheets does not // turn them into dates. // Decimal strings such as "1.0823" stay numbers. columns.forEach((name, index) => { const sample = rows.find( (row) => typeof row[name] === "string" && row[name] !== "", ); if (sample && !/^-?\d+(\.\d+)?$/.test(sample[name])) sheet.getRange(1, index + 1, values.length, 1).setNumberFormat("@"); }); sheet.getRange(1, 1, values.length, columns.length).setValues(values); } function pullAll() { pull("Holidays", "/v1/calendars/holidays/USA/2026", "holidays"); pull( "Releases", "/v1/economics/calendar?countries=USA&start_date=2026-11-01" + "&end_date=2026-11-30&limit=100", "releases", ); pull("CPI", "/v1/economics/USA/cpi/observations?start=2025-09", "observations"); pull("Brent", "/v1/commodities/spot/BRENT/USD", null); pull("FX", "/v1/fx/rates/USD?currencies=EUR,IDR", "rates"); pull("Fed", "/v1/predictions/policy-paths/federal-reserve", "meetings"); } - 執行 pullAll 在編輯器中執行
pullAll來填入各工作表。對於非空回應,輔助函式會先清空目標工作表,再寫入標題列和其後的資料,所以請把公式放在這些工作表之外。空清單不會寫入任何內容。它會從每一列中讀取欄名,因此第一個值為 null 也不會讓某一欄消失。
包含日期以及 2026-09 這類期間的文字欄會保持為純文字,這樣試算表就不會把它們轉成日期。以字串形式傳來的小數,如 1.0823,則保持為數字。下面的呼叫使用同樣的輔助函式、API 基礎 URL 和腳本屬性,各自指定目標工作表、請求路徑和回應欄位。
按排程定時執行
- 開啟觸發條件 使用 Apps Script 編輯器中的時鐘圖示開啟觸發條件。
- 新增時間驅動的觸發條件 為
pullAll新增一個時間驅動的觸發條件,例如每天執行一次。它呼叫的函式,與你在編輯器中填入資料工作表時呼叫的是同一個。
自訂函式也可以呼叫 URL Fetch,但每次試算表重新計算時它們都會重新執行,每次都會消耗一次請求;透過選單項目或時間驅動的觸發條件執行的函式,則只寫入一次值。
在 Google 試算表中查詢國定假日
把美國 2026 年的國定假日拉取到 Holidays。回應清單是 holidays,每個項目都有 date 和 name。輔助函式把這兩個欄位寫成欄,並保持日期文字不變。如果想讓假日資料列單獨放在一個工作表,就把這個呼叫和共用腳本一起使用。
pull(
"Holidays", "/v1/calendars/holidays/USA/2026", "holidays"
);
// Read date and name in the Holidays tab.在 Google 試算表中查詢發布日期
把美國 2026 年 11 月的經濟數據發布日曆拉取到 Releases。從回應中讀取 releases,每個項目都有 at、period、topic 和 status。這個請求針對的是發布日期;要取得各期間對應的經濟數值,請使用 CPI 觀測值的呼叫。
pull(
"Releases",
"/v1/economics/calendar?countries=USA&start_date=2026-11-01" +
"&end_date=2026-11-30&limit=100",
"releases",
);
// Read at, period, topic and status in the Releases tab.在 Google 試算表中查詢經濟數據
把請求起點設為 2025 年 9 月,將美國 CPI 觀測值拉取到 CPI。回應清單是 observations,工作表的欄是 period 和 value。第一次拉取後,請查看標題列。做月增率計算時,按期間文字查找每個月,這樣缺了某個月也不會讓公式錯位。
pull(
"CPI", "/v1/economics/USA/cpi/observations?start=2025-09", "observations"
);
// Read period and value in the CPI tab.要比較 2026 年 9 月與 2026 年 8 月,請在 CPI 工作表之外使用下面的公式。每個 VLOOKUP 在 CPI!A:B 中查找指定的月份;計算是用 9 月的值除以 8 月的值,再減去 1。
=VLOOKUP("2026-09",CPI!A:B,2,FALSE)/VLOOKUP("2026-08",CPI!A:B,2,FALSE)-1在 Google 試算表中查詢大宗商品現貨價格
把以 USD 計價的 Brent 現貨價格拉取到 Brent。price 欄位從回應物件中讀取。這個呼叫給清單鍵傳入 null,所以輔助函式把整個物件當作一列,並把各欄位寫在對應的欄名下。
pull(
"Brent", "/v1/commodities/spot/BRENT/USD", null
);
// Read price in the Brent tab.在 Google 試算表中查詢匯率
把以 USD 為基準的 EUR 和 IDR 匯率拉取到 FX。rates 清單的每個項目都有 currency 和 rate。讀取該工作表時,請把這兩欄放在一起,讓每個匯率都對應著它的貨幣。
pull(
"FX", "/v1/fx/rates/USD?currencies=EUR,IDR", "rates"
);
// Read currency and rate in the FX tab.在 Google 試算表中查詢預測市場機率
把聯準會政策路徑拉取到 Fed。回應清單是 meetings,每個項目都有 resolves_at、p_cut、p_hold 和 p_hike。請把結算時間和機率一起讀取,讓降息、維持不變和升息的機率都對應著各自的會議。
pull(
"Fed", "/v1/predictions/policy-paths/federal-reserve", "meetings"
);
// Read resolves_at, p_cut, p_hold and p_hike in the Fed tab.為什麼不用 IMPORTDATA 或 IMPORTXML?
IMPORTDATA 和 IMPORTXML 無法傳送 Authorization 標頭。Narwhal API 請求需要 Bearer 標頭,所以要用帶 UrlFetchApp 的 Apps Script 來發請求。輔助函式從腳本屬性中讀取金鑰,並在取得回應之前加上標頭。
可以把國定假日資料用於 NETWORKDAYS 嗎?
可以。把 Holidays 工作表的 date 欄用作 NETWORKDAYS 的假日引數。請使用該欄的日期,而不是假日名稱。此腳本中的假日請求提供的是美國 2026 年的假日日期。
為什麼 CPI 回應的起始期間可能晚於請求的期間?
所有帳戶都可讀取完整歷史。如果序列在請求的開始日期之後才開始,回應將從其第一個觀測值開始。
發布於 。