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

Implementation

How-To Guides

Como usar FXMacroData com o Google Apps Script e Google Sheets

Extrair dados de anúncio macroeconômico ao vivo do FXMacroData diretamente para o Google Sheets usando Apps Script com manipulação de limite de taxa, gatilhos de atualização automática e normalização de linha limpa para painéis de múltiplos indicadores.

Também disponível em English
Share article X LinkedIn Email

Google Sheets é o scratchpad do analista de macros: rápido de atualizar, fácil de compartilhar e já conectado ao resto do espaço de trabalho do Google. Google Apps Script O tempo de execução JavaScript incorporado no Google Sheet permite que você chame qualquer API REST de uma planilha sem sair do navegador. UrlFetchApp, lidar com limites de taxa e tentativas de reinicialização, normalizar respostas de múltiplos indicadores em linhas limpas e agendar atualizações automáticas para que o painel de controle de macro permaneça atualizado sem qualquer intervenção manual.

O que você vai construir

  • Um auxiliar de busca reutilizável liga para o FXMacroData através do UrlFetchApp com logia de tentativa de reinicialização e de retrocesso incorporada
  • Carregador de múltiplos indicadores recupera vários pares de moedas/indicadores e normaliza cada um numa linha plana de folha de cálculo
  • Um escritor de folhas cria ou redefine uma aba com nome, escreve cabeçalhos e adiciona linhas a cada execução
  • Um gatilho controlado pelo tempo actualiza automaticamente a folha todas as manhãs de dia útil

Requisitos prévios

  • Conta do Google qualquer conta com acesso a Google Sheets e Apps Script
  • Chave da API do FXMacroData Inscreva-se em / subscrever; muitos pontos finais de anúncio de USD são acessíveis ao público sem uma chave para testes iniciais
  • Não há software adicional Apps Script é executado inteiramente no navegador; não é necessário Node.js, Python ou ferramentas locais

- Passo 1 -

Passo 1 Crie uma planilha do Google e abra o editor de scripts Apps

Abre . folhas.google.com e criar uma nova planilha em branco. Dê-lhe um nome descritivo como Painel de controle FXMacroDataDepois abre o editor de scripts:

  1. Clique . Extensões na barra de menus de cima.
  2. Selecione Apps Script- Não .
  3. O editor abre numa nova aba com padrão Code.gs Ficheiro.
  4. Renomear o projeto (campo superior esquerdo) para FXMacroData Loader Para ser mais claro.

Todo o código que escreve aqui é executado no lado do servidor na infraestrutura do Google ele tem acesso ao completo UrlFetchApp O serviço pode ler e escrever a planilha através do SpreadsheetApp Serviço.

Dica: guarde sua chave de API como uma propriedade de script

Nunca codifique sua chave de API diretamente no script. Configurações do projeto → Propriedades do script → Adicionar propriedade e adicionar uma propriedade chamada FXMACRODATA_API_KEY As funções auxiliares abaixo lêem esta propriedade no tempo de execução através do PropertiesService.getScriptProperties()- Não .


- Passo 2 -

Passo 2 Escreva um auxiliar de busca com lógica de reintent

Coloque o seguinte código em Code.gs, substituindo a função de espaço reservado. UrlFetchApp.fetch com retrocesso exponencial, de modo que erros transitórios ou breves respostas de limite de taxa não matam a execução inteira.

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

Algumas coisas que vale a pena notar neste auxiliar:

  • muteHttpExceptions: true impede Apps Script de jogar em códigos não-200 você recebe o código de status e pode decidir o que fazer.
  • http 429 (Too Many Requests) desencadeia uma reatendimento com o dobro do atraso.
  • http 404 - Não significa normalmente que o indicador ainda não está disponível para essa moeda o auxiliar retorna null Então, a fila é ignorada.
  • Logger.log A saída é visível em Visualização → Registros no editor de scripts Apps, tornando a depuração simples.

- Passo 3 -

Passo 3 Normalize as respostas JSON em linhas de planilha

O ponto final de anúncios FXMacroData retorna um único objeto por par de moedas/indicadores. Para criar uma planilha útil, você precisa nivelar uma lista de solicitações em uma estrutura de linha consistente. Adicione a seguinte função de normalização abaixo fetchAnnouncement- Não .

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

O ... announcement_datetime O campo de FXMacroData tem uma precisão de segundo nível o momento exato em que o banco central ou a agência estatística publicou a leitura.

Sobre o ... consensus campo

Quando o campo está ausente, a API o omite do objeto de resposta, por isso data.consensus ?? '' escreve com segurança uma célula vazia em vez da cadeia "undefined"- Não .


- Passo 4 -

Passo 4 Escrever dados em uma guia do Google Sheets

Agora adicione a função de carregador principal que liga tudo: ele itera sobre uma lista de pares de moeda/indicador, chamadas fetchAnnouncement, converte cada resultado com toRow, e anexa as linhas a uma aba de folha dedicada.

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

Corram . loadMacroData manualmente do editor (clique ▶ CorraA primeira execução irá solicitar-lhe para autorizar o script clique Permissões de revisão → Permitir Para conceder acesso à planilha e às solicitações de rede externa.

Dica: adicionar uma função "Reset" para desenvolvimento

Durante o desenvolvimento é útil limpar a folha e re-executar a partir do zero.

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

- Passo 5 -

Passo 5 Limitações de taxa de gestão em grandes escalas de indicadores

O atraso de 200 ms entre solicitações no Passo 4 é suficiente para a lista de dez indicadores mostrada acima. Se você expandir para 50 ou mais pares cobrindo várias moedas em todo o catálogo de anúncios completo , você deve implementar um estrangulamento mais deliberado. Substitua o sono constante por uma pausa baseada em contador:

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

O ponto final de anúncio do FXMacroData é rápido cada resposta normalmente retorna em menos de 100 ms de um ambiente de execução de script do Google Apps. Utilities.sleep é a maneira mais simples de ficar dentro dos limites do seu plano sem batch ou cache lógica.


- O passo 6 .

Passo 6 Agendar atualizações automáticas com um gatilho orientado pelo tempo

Aplicações do Script. Ativadores O assistente seguinte cria um gatilho de manhã de dia de semana programaticamente execute-o uma vez do editor para registrá-lo, em seguida, excluir o próprio assistente:

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

Depois de correr . createWeekdayTrigger- Abre . Ativadores (icono de alarme-sino na barra lateral esquerda do editor) para confirmar cinco gatilhos aparecem um para cada dia da semana. Cada gatilho dispara entre 07:00 e 08:00 no fuso horário configurado para a sua conta do Google.

Alinhamento com o calendário de lançamento

Para uma abordagem mais cirúrgica, consulte o Ponto final do calendário de lançamento do FXMacroData No início de cada semana, para encontrar dias com anúncios de alto impacto programados, em seguida, apenas execute a varredura completa do indicador nesses dias.


- O passo 7 .

Passo 7 Pega no calendário de lançamento para pré-filtrar por dias de evento

O ... /v1/calendar/{currency} Endpoint retorna as próximas versões programadas para uma moeda. Use-o na segunda-feira para criar um conjunto de datas de anúncio para a semana, em seguida, pule a etapa de busca em dias sem eventos isso evita chamadas desnecessárias de API em semanas tranquilas.

/**
 * 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} */ função getAnnouncementDatesThisWeek(currency) { const apiKey = PropertiesService.getScriptProperties() .getProperty (('FXMACRODATA.getCode.getResponse.API_KEY') '; const url = https://fxmacrodata.com/api/v1/calendar/${currency}` + (apiKey ? `(((?api_key=${apiKee}` : ' ' '); const response = UrlFetch mute.Appfetch, {HttpExceptions: true }); if (response.getCalCode) == 200) = newset; const const retranslate = new); const Date fetches = JSON.Macdate.getFetchedData.getContent.getTexts (); const const const rest rest restores = new dates; const restores (data); constores (date); const restored (date) = data); const for today; const for $ (date).getData (date;data); restores; constores; restores de data); rest restored for today (date (date), *constores); const data const constores = data; const 'date); restored' (date'; restores 'date'; 'date;date); 'date'); const 'today); const;date (day); const (date}); const ('date); (date'): 'todays); 'todday); 'day); (day'); (date) (date=today;date; (date-day); ('today) (day) (d) (today). (date)). (date.events); (events) (event); (data) (de) (e) (s) (v.event) (D) (c) (this) (current) (a) (today) (ex.d) {events). (dete) (This) (new) (Event) (r) (n.d.d). (ev.d.) (d.e.d); (e.e) {d) } (d.) { (d} (d); 'e) }) (now) (no); (todays

Para utilizar este padrão, registe-se loadMacroDataCalendarAware como o manipulador do gatilho em vez de loadMacroData substituir a cadeia de nomes de funções em createWeekdayTrigger Em conformidade.


- Resumo -

Resumo

Agora você tem um pipeline completo, pronto para produção que conecta FXMacroData para Google Sheets através de Apps Script:

  • Um auxiliar de busca com tentativa de reinicialização e back-off exponencial que lida com erros de rede transitórios e respostas de limite de taxa com graça.
  • Uma função de normalização que converte cada resposta de anúncio em uma linha de planilha consistente e segura de deduplicação.
  • Um redator de folhas que cria cabeçalhos na primeira execução, anexa apenas novos lançamentos e pula os vistos anteriormente announcement_datetime valores.
  • A redução adaptativa para barragens a granel em dezenas de pares de moedas/indicadores.
  • Um gatilho de dia de semana para atualizações diárias totalmente automatizadas.
  • Uma pré-verificação de calendário opcional que evita chamadas de API redundantes em dias sem lançamentos agendados.

Próximos passos

  • Aumentar a lista de indicadores consulte o catálogo completo em /api-data-docs e adicionar pares relevantes para a sua estratégia (por exemplo chf/gov_bond_10y- Não . eur/pmi- Não . gbp/employment)
  • Adicionar formatação condicional realçar linhas onde Direção É ... Beat - Em verde e ... Miss em vermelho usando SpreadsheetAppÉ ... ConditionalFormatRuleBuilder para leitura de sinal de um olhar.
  • Alertas de push para Slack ou e-mail após adicionar linhas, utilizar MailApp.sendEmail ou uma chamada de webhook lá dentro . loadMacroData para notificar a sua equipa quando uma impressão de alta incidência chegar.
  • Acompanhe os valores históricos o Anúncios ponto final também aceita . start_date - Não . end_date Parâmetros executar um recheio único em um intervalo de datas mais longo para semear uma guia histórica ao lado da alimentação ao vivo.

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/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.

Share page X LinkedIn Email