Live release feed
Sub-second macro releases for FX backtests
Point-in-time history
Official CPI, jobs, GDP, and central-bank events with point-in-time history.
$25/month 14-day free trial
Start Free Trial
How To Use Fxmacrodata With Google Apps Script And Google Sheets image
Share headline card X LinkedIn Email
Download

Implementation

How-To Guides

How To Use Fxmacrodata With Google Apps Script And Google Sheets

Pull live macroeconomic announcement data from FXMacroData directly into Google Sheets using Apps Script — with rate-limit handling, automatic refresh triggers, and clean row normalization for multi-indicator dashboards.

Juga tersedia dalam English
Share article X LinkedIn Email

Google Sheets adalah scratchpad analis makro: cepat untuk memperbarui, mudah untuk berbagi, dan sudah terhubung ke ruang kerja Google lainnya. Google Apps Script Sheets' built-in JavaScript runtime memungkinkan Anda memanggil REST API dari spreadsheet tanpa meninggalkan browser. Panduan ini berjalan melalui menarik data pengumuman FXMacroData ke tab Sheets dengan UrlFetchApp, menangani batas laju dan uji ulang, normalisasi respons multi-indikator ke baris bersih, dan menjadwalkan pembaruan otomatis sehingga dasbor makro Anda tetap terkini tanpa intervensi manual.

Apa yang akan Anda bangun

  • Pembantu mengambil yang dapat digunakan kembali panggilan FXMacroData melalui UrlFetchApp dengan built-in try ulang dan back-off logika
  • Sebuah loader multi-indikator mengambil beberapa pasangan mata uang/indikator dan menormalkan masing-masing ke dalam baris spreadsheet datar
  • Seorang penulis Sheets membuat atau mengatur ulang tab bernama, menulis header, dan menambahkan baris dengan setiap menjalankan
  • Pemicu yang didorong waktu memperbarui lembar secara otomatis setiap pagi hari kerja

Persyaratan

  • Akun Google setiap akun dengan akses ke Google Sheets dan Apps Script
  • Kunci API FXMacroData daftar di /langganan; banyak titik akhir pengumuman USD dapat diakses publik tanpa kunci untuk pengujian awal
  • Tidak ada perangkat lunak tambahan Aplikasi Script berjalan sepenuhnya di browser; tidak diperlukan Node.js, Python, atau alat lokal

- Langkah 1 -

Langkah 1 Buat Google Sheet dan buka editor skrip Apps

Buka. sheets.google.com dan buat spreadsheet kosong baru. berikan nama deskriptif seperti FXMacroData DashboardKemudian buka editor skrip:

  1. Klik Perpanjangan di menu bar atas.
  2. Pilih Aplikasi ScriptAku tidak tahu.
  3. Editor dibuka di tab baru dengan default Code.gs file.
  4. Mengganti nama proyek (bidang kiri atas) menjadi FXMacroData Loader untuk kejelasan.

Semua kode yang Anda tulis di sini berjalan di sisi server pada infrastruktur Google memiliki akses ke penuh UrlFetchApp layanan dan dapat membaca dan menulis spreadsheet melalui SpreadsheetApp layanan.

Tips: simpan kunci API Anda sebagai properti Script

Jangan pernah hard-code kunci API Anda langsung di script. Pengaturan Proyek → Properti Skrip → Tambahkan properti dan tambahkan properti bernama FXMACRODATA_API_KEY Dengan kunci Anda sebagai nilai. Fungsi pembantu di bawah ini membaca properti ini pada saat runtime melalui PropertiesService.getScriptProperties().


- Langkah 2 -

Langkah 2 Tulis bantuan pengambilan dengan logika uji ulang

Tempelkan kode berikut di Code.gs, menggantikan fungsi placeholder. UrlFetchApp.fetch dengan back-off eksponensial sehingga kesalahan sementara atau respons batas laju singkat tidak membunuh seluruh run.

/**
 * 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;
}

Beberapa hal yang perlu diperhatikan dalam bantuan ini:

  • muteHttpExceptions: true mencegah Aplikasi Script dari melemparkan pada non-200 kode Anda mendapatkan kode status dan dapat memutuskan apa yang harus dilakukan.
  • HTTP 429 (Terlalu Banyak Permintaan) memicu upaya ulang dengan penundaan dua kali lipat. FXMacroData memberlakukan batas tingkat per kunci; strategi back-off sederhana menjaga skrip dalam anggaran di seluruh penggeser indikator penuh.
  • HTTP 404 biasanya berarti indikator belum tersedia untuk mata uang tersebut pembantu kembali null jadi barisnya dilewatkan dengan bersih.
  • Logger.log output terlihat di bawah Tampilan → Log di editor skrip aplikasi, membuat debugging mudah.

- Langkah 3 -

Langkah 3 Normalisasi tanggapan JSON ke baris spreadsheet

FXMacroData announcements endpoint mengembalikan satu objek per pasangan mata uang/indikator. Untuk membangun spreadsheet yang berguna, Anda perlu meratakan daftar permintaan ke dalam struktur baris yang konsisten. Tambahkan fungsi normalisasi berikut di bawah ini fetchAnnouncementAku tidak tahu.

/**
 * 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
  ];
}

- Apa? announcement_datetime kolom dari FXMacroData membawa tingkat kedua presisi saat tepat bank sentral atau lembaga statistik menerbitkan pembacaan. time stamp itu ideal sebagai kunci deduplikasi: Anda dapat memeriksa apakah baris dengan timestamp ini sudah ada di lembar sebelum menambahkan, mencegah baris duplikat pada kali berulang.

Tentang... consensus lapangan

Tidak semua indikator membawa nilai konsensus / perkiraan. Ketika bidang tidak ada API melewatkannya dari objek respons, jadi data.consensus ?? '' dengan aman menulis sel kosong daripada string "undefined".


- Langkah 4 -

Langkah 4 Tulis data ke tab Google Sheets

Sekarang tambahkan fungsi loader utama yang menghubungkan semuanya bersama-sama: itu berulang-ulang di atas daftar pasangan mata uang / indikator, panggilan fetchAnnouncement, mengkonversi setiap hasil dengan toRow, dan menambahkan baris ke tab lembar khusus.

/**
 * 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.');
  }
}

Larilah. loadMacroData dengan manual dari editor (klik ▶ LarilahUntuk mengaktifkan program ini, Anda harus mengklik tombol "Authorise" (mengaktifkan) untuk menguji pipeline sebelum mengatur pemicu. Permit Review → Izinkan Untuk memberikan akses ke spreadsheet dan permintaan jaringan eksternal.

Tip: tambahkan fungsi "Reset" untuk pengembangan

Selama pengembangan, berguna untuk menghapus lembar dan menjalankan kembali dari awal.

function resetSheet() {
  const ss    = SpreadsheetApp.getActiveSpreadsheet();
  const sheet = ss.getSheetByName(SHEET_NAME);
  if (sheet) ss.deleteSheet(sheet);
  loadMacroData(); // recreates with fresh headers and data
}

- Langkah 5 -

Langkah 5 Mengatur batas tingkat di seluruh penggeser indikator yang lebih besar

Penundaan 200 ms antar permintaan pada Langkah 4 cukup untuk daftar sepuluh indikator yang ditunjukkan di atas. Jika Anda memperluas ke 50 atau lebih pasangan yang mencakup beberapa mata uang di seluruh katalog pengumuman penuh Anda harus menerapkan penekanan yang lebih disengaja. Ganti tidur konstan dengan jeda berbasis konter:

/**
 * 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 pengumuman titik akhir cepat setiap respon biasanya kembali dalam waktu kurang dari 100 ms dari lingkungan eksekusi Google Apps Script. Utilities.sleep adalah cara termudah untuk tetap dalam batas rencana Anda tanpa batching atau caching logika.


- Langkah 6 -

Langkah 6 Jadwalkan pembaruan otomatis dengan pemicu yang didorong waktu

Aplikasi Script's Pemicu sistem memungkinkan Anda menjalankan fungsi apa pun pada jadwal tanpa dedicated server. Helper berikut membuat pemicu pagi hari kerja secara programmatic menjalankan sekali dari editor untuk mendaftarkannya, kemudian hapus helper itu sendiri:

/**
 * 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.');
}

Setelah lari. createWeekdayTriggerBuka. Pemicu (ikon lonceng alarm di bilah sisi kiri editor) untuk mengkonfirmasi lima pemicu muncul satu untuk setiap hari kerja. Setiap pemicu menyala antara 07:00 dan 08:00 di zona waktu yang dikonfigurasi untuk akun Google Anda.

Menyelaraskan dengan kalender rilis

Untuk pendekatan yang lebih bedah, pertanyaan FXMacroData release endpoint kalender Pada awal setiap minggu untuk menemukan hari dengan jadwal pengumuman berdampak tinggi, kemudian hanya menjalankan penggeser indikator penuh pada hari-hari itu.


- Langkah 7 -

Langkah 7 Ambil kalender rilis untuk pra-filter dengan hari acara

- Apa? /v1/calendar/{currency} Endpoint mengembalikan rilis yang dijadwalkan untuk mata uang. Gunakan pada hari Senin untuk membangun satu set tanggal pengumuman untuk minggu, kemudian lewatkan langkah pengambilan pada hari tanpa acara ini menghindari panggilan API yang tidak perlu pada minggu yang tenang.

/**
 * 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. */ fungsi loadMacroDataCalendarAware() { const today = new Date().toISOString().slice(0, 10); const currencies = ['usd', 'eur', 'chf', 'gbp']; const hasEvents = currencies.some(c => { const dates = getAnnouncementDatesThisWeek(c); return dates.has(today); }); if (!hasEvents) { Logger.log`No scheduled releases for today (${today}).Skip fetch.`); return; } Logger .log`Release events found for ${todays}. Running full macro fetch .`); fetroMacrodata; }

Untuk menggunakan pola ini, daftarkan loadMacroDataCalendarAware sebagai pemegang pemicu alih-alih loadMacroData mengganti string nama fungsi dengan createWeekdayTrigger Dengan demikian.


- Ringkasan -

Ringkasan

Anda sekarang memiliki pipa produksi siap lengkap yang menghubungkan FXMacroData ke Google Sheets melalui Aplikasi Script:

  • Pembantu pengambilan dengan upaya ulang dan back-off eksponensial yang menangani kesalahan jaringan sementara dan respon batas kecepatan dengan anggun.
  • Fungsi normalisasi yang mengkonversi setiap respon pengumuman menjadi baris spreadsheet yang konsisten dan aman untuk deduplikasi.
  • Sebuah penulis lembar yang membuat header pada saat pertama kali dijalankan, hanya menambahkan rilis baru, dan melewatkan yang sebelumnya terlihat announcement_datetime nilai.
  • Adaptive throttling untuk penggeser massal di puluhan pasangan mata uang / indikator.
  • Pemicu yang dikendalikan waktu untuk pembaruan harian otomatis.
  • Pemeriksaan awal kalender opsional yang menghindari panggilan API yang berlebihan pada hari-hari tanpa rilis terjadwal.

Langkah selanjutnya

  • Perluas daftar indikator melihat katalog lengkap di /api-data-docs dan tambahkan pasangan yang relevan dengan strategi Anda (misalnya chf/gov_bond_10yAku akan pergi. eur/pmiAku akan pergi. gbp/employment)
  • Tambahkan pemformatan bersyarat menyorot baris dimana Arah adalah Beat di hijau dan Miss dengan menggunakan warna merah SpreadsheetApp- Itu ... ConditionalFormatRuleBuilder untuk membaca sinyal sekilas.
  • Push alert ke Slack atau email setelah menambahkan baris, gunakan MailApp.sendEmail atau panggilan webhook di dalam. loadMacroData untuk memberi tahu tim Anda ketika cetakan berdampak tinggi tiba.
  • Pelacakan nilai-nilai historis yang pengumuman titik akhir juga menerima start_date / end_date parameter menjalankan satu kali backfill pada rentang tanggal yang lebih panjang untuk benih tab historis di samping feed hidup.

Blogroll

AI Answer-Ready

Key Facts

Page
How To Use FXmacrodata With Google Apps Script And Google Sheets
Section
Articles
Canonical URL
https://fxmacrodata.com/id/articles/how-to-use-fxmacrodata-with-google-apps-script-and-google-sheets
Source
FXMacroData editorial and official publisher references
Last Updated
2026-06-15 11:06 UTC

Provenance And Trust

Cite the canonical URL and source field above. Where available, this page maps to official publisher releases and timestamped updates.

Quick Q&A

What is this page about? This page explains How To Use FXmacrodata With Google Apps Script And Google Sheets with directly usable context for trading, research, and API workflows.

What source should be cited? Use the canonical URL and the listed source field; cite official publisher references when available.

How fresh is this content? The last updated value above reflects the page metadata or latest available data timestamp.

Can this be used in AI assistants? Yes. This section is intentionally structured for retrieval and citation in chat assistants.

Prompt Packs

Use these in ChatGPT, Claude, Gemini, Mistral, Perplexity, or Grok for consistent source-aware outputs.