Google Sheets はマクロアナリストのスクラッチパッドです.更新が迅速で共有が簡単で,すでにGoogleの他のワークスペースに接続されています. Google Apps スクリプト Sheets の内蔵 JavaScript ランタイム は,ブラウザを離さずにスプレッドシートから任意の REST API を呼び出すことができます.このガイドでは,FXMacroData の発表データを Sheets タブに引き込むことを説明します. UrlFetchAppマクロダッシュボードが手動の介入なしに更新されるように,自動更新をスケジュールします. 自動更新は,マクロダシュボードの動作を調整します.
建設する
- 再利用可能な取っ取りのヘルパー FXMacroData を呼び出し
UrlFetchApp組み込み再試行とバックオフ論理 - 複数の指示器を搭載する荷装機 数つの通貨/指標ペアを検索し,各ペアに平らなスプレッドシート列を標準化します
- シーツの作家 名前付けタブを作成したりリセットしたり,ヘッダを書いて,各実行で行を追加します
- タイム・ドライブ・トリガー 毎朝,自動的に更新します
条件
- Google アカウント Google Sheets と Apps Script にアクセスできるアカウント
- FXMacroData API キーを 登録する / サブスクリプト初期テスト用の鍵なしで公開されている.
- 追加ソフトウェアがない Apps スクリプトはブラウザで完全に実行されます. Node.js,Python,ローカルツールなど不要です.
ステップ 1
ステップ 1 Googleシートを作成して Apps スクリプトエディタを開きます
オープン シーツ.グーグル.com 書き換えると,このページの名前が FXMacroData ダッシュボード脚本編集を開きます
- クリック 拡張 上のメニューバーに
- 選択する アプリスクリプトわかった
- 編集者は新しいタブで開きます.
Code.gsファイル - プロジェクト (左上のフィールド) の名前を変更します FXMacroData ロードヤー 明確になるため
サーバー側でGoogleのインフラストラクチャで実行されます 完全にアクセスできます UrlFetchApp 計算表を読み書きできる
SpreadsheetApp サービス
提示: API キーをスクリプトプロパティとして保存する
文字の中に直接APIキーをコードするな
プロジェクト設定 → スクリプトプロパティ → プロパティを追加 変数で表示される
FXMACRODATA_API_KEY 実行時にこのプロパティを読み取ります. PropertiesService.getScriptProperties()ほら
ステップ2
ステップ2 復試論理を持つ取得ヘルパーを書く
入力してください Code.gs補完機能が入れ替わります この補完プログラムが UrlFetchApp.fetch 短時間の速度の制限応答は 実行全体を破壊しないようにします.
/**
* Fetches a FXMacroData endpoint with automatic retry and exponential back-off.
*
* @param {string} currency - e.g. "usd", "eur", "chf"
* @param {string} indicator - e.g. "policy_rate", "gdp", "inflation"
* @returns {Object|null} - Parsed JSON response, or null on permanent failure
*/
function fetchAnnouncement(currency, indicator) {
const apiKey = PropertiesService.getScriptProperties()
.getProperty('FXMACRODATA_API_KEY') || '';
const url = `https://fxmacrodata.com/api/v1/announcements/${currency}/${indicator}`
+ (apiKey ? `?api_key=${apiKey}` : '');
const maxRetries = 4;
let delay = 1000; // 1 second initial back-off
for (let attempt = 1; attempt <= maxRetries; attempt++) {
try {
const response = UrlFetchApp.fetch(url, { muteHttpExceptions: true });
const status = response.getResponseCode();
if (status === 200) {
return JSON.parse(response.getContentText());
}
if (status === 429) {
// Rate limited — honour the back-off and retry
Logger.log(`Rate limited on attempt ${attempt}. Waiting ${delay}ms.`);
Utilities.sleep(delay);
delay *= 2; // exponential back-off
continue;
}
if (status === 404) {
Logger.log(`No data for ${currency}/${indicator} (404). Skipping.`);
return null;
}
// Other non-retryable errors
Logger.log(`HTTP ${status} for ${currency}/${indicator}.`);
return null;
} catch (e) {
Logger.log(`Network error on attempt ${attempt}: ${e.message}`);
Utilities.sleep(delay);
delay *= 2;
}
}
Logger.log(`Permanently failed after ${maxRetries} attempts: ${currency}/${indicator}`);
return null;
}
このヘルパーに注目すべき点は
muteHttpExceptions: trueprevents Apps Script from throwing on non-200 codes — you get the status code and can decide what to do.- メールの送信 429 について (RECOMMENDATIONS TOO MANY) は,遅延を倍にする再試行を誘発する.FXMacroDataは,キー毎のレート制限を強制する.控えめなバックオフ戦略は,完全な指標スイープを通じてスクリプトを予算内に保持する.
- メールの送信 404 について 補助者が返信する
null順番をクリーンに跳ねました Logger.log画面の下には 閲覧 → ログ 簡単にデバッグできます. 簡単に,簡単に,簡単です.
ステップ3
Step 3 — Normalize JSON responses into spreadsheet rows
FXMacroData 発表エンドポイントは,通貨/指標ペアごとに単一のオブジェクトを返します.有用なスプレッドシートを構築するには,リクエストリストを一貫した行構造に平ら化する必要があります.以下の標準化関数を下に追加します. fetchAnnouncementありがとうございました
/**
* Converts a FXMacroData announcement response object into a flat array
* suitable for appending as a single Sheets row.
*
* Columns: Timestamp, Currency, Indicator, Value, Prior, Consensus,
* Announcement DateTime, Direction
*
* @param {Object} data - Parsed JSON from fetchAnnouncement()
* @returns {Array} - Flat row array
*/
function toRow(data) {
if (!data) return null;
const direction =
data.val > data.prior ? 'Beat' :
data.val < data.prior ? 'Miss' : 'In line';
return [
new Date().toISOString(), // Run timestamp
(data.currency || '').toUpperCase(),
(data.indicator || '').replace(/_/g, ' '),
data.val ?? '',
data.prior ?? '',
data.consensus ?? '',
data.announcement_datetime || '',
direction
];
}
ほら announcement_datetime FXMacroDataのフィールドは,中央銀行または統計機関が読み上げを公開した正確な瞬間に二次レベルの精度を保持しています. そのタイムスタンプは,デデュプリケーションキーとして理想的です.このタイムスタンプルを持つ行が既にシート内に存在するかどうかを追加する前に確認し,繰り返し実行する際に重複する行を防ぐことができます.
について consensus フィールド
すべての指標にはコンセンサス/予測値が伴わない.フィールドが欠落すると,APIは応答オブジェクトからそれを省略します. data.consensus ?? '' 文字列ではなく空のセルを安全に書き込む "undefined"ほら
ステップ4
ステップ4 データをGoogleシートタブに書き込む
通貨/指標ペアのリストを繰り返す 呼び出し fetchAnnouncement変換する
toRowページのタブに列を添付する.
/**
* Defines the currency/indicator pairs to track.
* Extend this list to cover additional signals for your strategy.
*/
const INDICATORS = [
{ currency: 'usd', indicator: 'policy_rate' },
{ currency: 'usd', indicator: 'inflation' },
{ currency: 'usd', indicator: 'non_farm_payrolls' },
{ currency: 'eur', indicator: 'policy_rate' },
{ currency: 'eur', indicator: 'inflation' },
{ currency: 'chf', indicator: 'gdp' },
{ currency: 'chf', indicator: 'consumer_confidence' },
{ currency: 'chf', indicator: 'gov_bond_10y' },
{ currency: 'gbp', indicator: 'policy_rate' },
{ currency: 'gbp', indicator: 'inflation' },
];
const SHEET_NAME = 'MacroData';
const HEADERS = [
'Run Timestamp', 'Currency', 'Indicator', 'Value',
'Prior', 'Consensus', 'Announcement DateTime', 'Direction'
];
/**
* Main entry point — fetches all configured indicators and
* appends new rows to the MacroData sheet tab.
*/
function loadMacroData() {
const ss = SpreadsheetApp.getActiveSpreadsheet();
let sheet = ss.getSheetByName(SHEET_NAME);
// Create the tab if it does not exist yet
if (!sheet) {
sheet = ss.insertSheet(SHEET_NAME);
sheet.appendRow(HEADERS);
sheet.getRange(1, 1, 1, HEADERS.length)
.setFontWeight('bold')
.setBackground('#1a73e8')
.setFontColor('#ffffff');
sheet.setFrozenRows(1);
}
// Build a set of existing announcement_datetimes to avoid duplicates
const lastRow = sheet.getLastRow();
const existing = new Set();
if (lastRow > 1) {
const dtCol = 7; // "Announcement DateTime" is column 7 (index 6, 1-based col 7)
const values = sheet.getRange(2, dtCol, lastRow - 1, 1).getValues();
values.forEach(([dt]) => { if (dt) existing.add(String(dt)); });
}
const newRows = [];
INDICATORS.forEach(({ currency, indicator }) => {
// Throttle requests — 200 ms between calls keeps well within rate limits
Utilities.sleep(200);
const data = fetchAnnouncement(currency, indicator);
const row = toRow(data);
if (!row) return; // skip null / error responses
const announcementDt = row[6]; // announcement_datetime column
if (existing.has(announcementDt)) {
Logger.log(`Skipping duplicate: ${currency}/${indicator} @ ${announcementDt}`);
return;
}
newRows.push(row);
existing.add(announcementDt); // guard against duplicates within the same run
});
if (newRows.length > 0) {
sheet.getRange(sheet.getLastRow() + 1, 1, newRows.length, HEADERS.length)
.setValues(newRows);
Logger.log(`Appended ${newRows.length} new row(s) to "${SHEET_NAME}".`);
} else {
Logger.log('No new rows — all announcements already present.');
}
}
逃げろ loadMacroData 編集から手動で (クリック) ▶ 走れ実行する際に,スクリプトを承認するように要求されます.
閲覧 → 許可する スプレッドシートと外部ネットワークのリクエストへのアクセスを許可する.
開発のために"リセット"関数を追加
開発中にシートをクリアしてゼロから再起動することが有用です.小さなヘルパーを追加します:
function resetSheet() {
const ss = SpreadsheetApp.getActiveSpreadsheet();
const sheet = ss.getSheetByName(SHEET_NAME);
if (sheet) ss.deleteSheet(sheet);
loadMacroData(); // recreates with fresh headers and data
}
ステップ5
ステップ 5 幅の大きい指標のスイープでレート制限を調整する
The 200 ms inter-request delay in Step 4 is sufficient for the ten-indicator list shown above. If you expand to 50 or more pairs — covering multiple currencies across the full announcement catalogue — you should implement more deliberate throttling. Replace the constant sleep with a counter-based pause:
/**
* Fetches a larger list of indicators with adaptive throttling.
* Pauses for 1 second every 10 requests to respect rate limits.
*/
function loadMacroDataBulk(indicators) {
const ss = SpreadsheetApp.getActiveSpreadsheet();
let sheet = ss.getSheetByName(SHEET_NAME) || (() => {
const s = ss.insertSheet(SHEET_NAME);
s.appendRow(HEADERS);
s.getRange(1, 1, 1, HEADERS.length)
.setFontWeight('bold')
.setBackground('#1a73e8')
.setFontColor('#ffffff');
s.setFrozenRows(1);
return s;
})();
const newRows = [];
let count = 0;
indicators.forEach(({ currency, indicator }) => {
count++;
// Longer pause every 10 requests
if (count % 10 === 0) {
Logger.log(`Pausing after ${count} requests…`);
Utilities.sleep(1500);
} else {
Utilities.sleep(150);
}
const data = fetchAnnouncement(currency, indicator);
const row = toRow(data);
if (row) newRows.push(row);
});
if (newRows.length > 0) {
sheet.getRange(sheet.getLastRow() + 1, 1, newRows.length, HEADERS.length)
.setValues(newRows);
}
Logger.log(`Bulk load complete — ${newRows.length} rows appended.`);
}
FXMacroDataの発表エンドポイントは高速です.各応答は通常,Google Apps スクリプト実行環境から100ms未満で返信されます.大規模なスイープにおける主なボトルネックは,遅延ではなく,キーごとに要求する予算です. Utilities.sleep ブロックやキャッシュの論理なしでプランの限界内に留まる最も簡単な方法です.
ステップ6
ステップ6 タイム駆動トリガーで自動更新をスケジュールする
脚本が使われています 誘発器 プログラムで平日の朝のトリガーを作成します. 編集から一度実行して登録し,その後ヘルパー自体を削除します.
/**
* Registers a time-driven trigger that runs loadMacroData()
* every weekday between 07:00 and 08:00 UTC.
*
* Run this function ONCE from the Apps Script editor to set up the trigger.
* You do not need to call it again — it persists in the project.
*/
function createWeekdayTrigger() {
// Remove any existing triggers for loadMacroData to avoid duplicates
ScriptApp.getProjectTriggers()
.filter(t => t.getHandlerFunction() === 'loadMacroData')
.forEach(t => ScriptApp.deleteTrigger(t));
ScriptApp.newTrigger('loadMacroData')
.timeBased()
.everyWeeks(1)
.onWeekDay(ScriptApp.WeekDay.MONDAY)
.atHour(7)
.create();
// Also register Tuesday through Friday
[
ScriptApp.WeekDay.TUESDAY,
ScriptApp.WeekDay.WEDNESDAY,
ScriptApp.WeekDay.THURSDAY,
ScriptApp.WeekDay.FRIDAY,
].forEach(day => {
ScriptApp.newTrigger('loadMacroData')
.timeBased()
.everyWeeks(1)
.onWeekDay(day)
.atHour(7)
.create();
});
Logger.log('Weekday triggers registered for loadMacroData.');
}
走った後 createWeekdayTriggerオープン 誘発器 (alarm-bell icon in
the left sidebar of the editor) to confirm five triggers appear — one for each weekday. Each trigger
fires between 07:00 and 08:00 in the time zone configured for your Google account.
リリースカレンダーに準拠
治療方法について 詳しくは FXMacroData のリリース カレンダー エンドポイント 実行時間が短く,APIの使用量は静かなカレンダー週に低くなります. 実行時間は短くなります.
ステップ7
ステップ 7 公開カレンダーをイベント日によって前フィルタに取得
ほら /v1/calendar/{currency} endpoint は,通貨の予定されたリリースを返します. 月曜日にそれを使って,その週の発表日付をセットを作成し,イベントのない日に取得ステップをスキップします.
/**
* Returns a Set of date strings ("YYYY-MM-DD") for which at least one
* high-impact announcement is scheduled this week for the given currency.
*
* @param {string} currency - e.g. "usd"
* @returns {Set}
*/
function getAnnouncementDatesThisWeek(currency) {
const apiKey = PropertiesService.getScriptProperties()
.getProperty('FXMACRODATA_API_KEY') || '';
const url = `https://fxmacrodata.com/api/v1/calendar/${currency}`
+ (apiKey ? `?api_key=${apiKey}` : '');
const response = UrlFetchApp.fetch(url, { muteHttpExceptions: true });
if (response.getResponseCode() !== 200) return new Set();
const releases = JSON.parse(response.getContentText());
const today = new Date();
const weekEnd = new Date(today);
weekEnd.setDate(today.getDate() + 7);
const dates = new Set();
(releases || []).forEach(event => {
if (!event.release_date) return;
const d = new Date(event.release_date);
if (d >= today && d <= weekEnd) {
dates.add(event.release_date.slice(0, 10));
}
});
return dates;
}
/**
* Calendar-aware version of loadMacroData. * Only runs the full indicator fetch if today has scheduled releases. */関数ロードMacroDataCalendarAware (() { const today = new Date (().toISOString (().slice ((0, 10); const 通貨 = ['usd', 'eur', 'chf', 'gbp']; const hasEvents = currencies.some ((c => { const dates = getAnnouncementDatesThisWeek ((c); return dates.has(today); }); if (!hasEvents) { Logger.log`今日予定されているリリースはありません (${today}). fetch.`をスキップ); return; } Logger .log`Release ${todays}.
このパターンを使うには 登録してください loadMacroDataCalendarAware 引き金を引く代わりに loadMacroData 函数名文字列を に置き換える createWeekdayTrigger
適正に
── 概要 ──
概要
ソフトウェアスクリプトでFXMacroDataとGoogleシートを接続します. ソフトウェアの作成は,
- 復試と指数関数バックオフの 呼び出すヘルパーで 臨時的なネットワークエラーと速度制限応答を 優雅に処理します
- 標準化関数で,各発表応答を一貫したデデュプリケーション安全のスプレッドシート行に変換する.
- プレスリリースでヘッダを作成し,新しいリリースのみを追加し,以前見ていたものをスキップします
announcement_datetime価値 - 適応型ストロッシング 貨幣/指標ペアを数十種類を対象とした大量スイープ
- 完全自動化された日々の更新のための平日の時間駆動トリガーです
- 予定されていない日に冗長な API 呼び出しを避けるオプションのカレンダープレチェック.
次のステップ
-
指標リストを拡大する 完全なカタログを閲覧してください
/api-data-docs ファイルファイル
戦略に合ったペアを追加します (例えば
chf/gov_bond_10yほらeur/pmiほらgbp/employment) について -
条件式フォーマットを追加する 列を強調する 方向性 やってる
Beat緑色でMiss赤い色でSpreadsheetAppほらConditionalFormatRuleBuilder信号を一目で読み取れる -
Slack またはメールに警告をプッシュする 列を添付した後,使用します
MailApp.sendEmailウェブホックで電話をloadMacroData発信されたときに チームに通知します -
歴史的価値を追跡する
発表 終了点
受け入れます
start_date/end_date設定する 長い日付範囲で一度のバックフィールを実行して,ライブフィードの横に歴史タブをシードします.