Build a Real-Time FX Event Agent That Front-Runs Your Morning Prep banner image

Implementation

How-To Guides

Build a Real-Time FX Event Agent That Front-Runs Your Morning Prep

Replace 45 minutes of manual pre-market prep with an always-on AI agent that scans the FXMacroData release calendar, ranks today's events by market impact, and delivers a structured briefing before London open.

Também disponível em English

Porque um agente de preparação da manhã é o bot de maior ROI que você pode construir primeiro

Se você negociar FX discretariamente ou executar um livro semi-automático, os 45 minutos mais caros do seu dia são aqueles antes de Londres abrir. Calendário de lançamento, verificando quais impressões são de nível um, procurando por consenso, escaneando movimentos durante a noite USD/JPY- Não . EUR/USD- Não . GBP/USDÉ repetitivo, propenso a erros e obriga-nos a reconstruir o contexto todas as manhãs do zero.

Este é exatamente o tipo de tarefa que um agente de IA faz melhor do que um humano: escopo limitado, entradas estruturadas, saída determinista. Agente de eventos FX em tempo real que é executado antes do seu dia de negociação, extrai dados de eventos ao vivo do FXMacroData, classifica os lançamentos de hoje por impacto provável no mercado, e fornece um briefing estruturado que você pode ler em 90 segundos.

No final, você terá um script que pode agendar em qualquer máquina laptop, Raspberry Pi, nuvem VM que transforma a preparação da manhã de uma tarefa em uma lista de verificação.

O que você vai construir
Um agente Python que é executado às 06:30 UTC diariamente, consulta o calendário de lançamento do FXMacroData para as próximas 24 horas em todo o G10, classifica eventos por impacto, resume-os através de um LLM e empurra um briefing estruturado para Telegram ou Slack.

Requisitos prévios

  • Python 3.10+ e pip.
  • Uma chave de API do FXMacroData Gestão de API- Não .
  • Um ponto final de LLM que controla.
    • Antropic Claude (recomendado para a qualidade do raciocínio).
    • OpenAI GPT-4 de classe.
    • Hermes/Llama local via Ollama para corridas de custo zero.
  • Um token do Telegram bot (via @BotFather) ou um Slack URL de webhook funcione como o canal de entrega.
  • Um agendador. cron no Linux/macOS, no Planeador de Tarefas no Windows, ou qualquer cron na nuvem irá fazer.

Instalar dependências:

pip install requests python-dotenv

Crie um .env Ficheiro com os teus segredos:

FXMD_API_KEY=your_fxmacrodata_key
LLM_PROVIDER=anthropic           # or "openai" or "ollama"
ANTHROPIC_API_KEY=sk-ant-...
TELEGRAM_BOT_TOKEN=...
TELEGRAM_CHAT_ID=...

Passo 1: extrair as próximas 24 horas do calendário de lançamento do FXMacroData

O primeiro trabalho do agente é saber o que está realmente programado. FXMacroData O calendário de lançamento retorna os pontos finais de lancamentos programados por moeda, incluindo o nome do indicador, a hora de data UTC programada, o valor anterior e a classificação de importância, se disponíveis.

Pergunte-a para cada moeda principal que você negocia:

curl "https://fxmacrodata.com/api/v1/calendar/usd?api_key=YOUR_API_KEY"
curl "https://fxmacrodata.com/api/v1/calendar/eur?api_key=YOUR_API_KEY"
curl "https://fxmacrodata.com/api/v1/calendar/gbp?api_key=YOUR_API_KEY"
curl "https://fxmacrodata.com/api/v1/calendar/jpy?api_key=YOUR_API_KEY"

Enrole isso em Python para que o agente possa iterar em uma lista de moedas configurável:

import os
import requests
from datetime import datetime, timedelta, timezone
from dotenv import load_dotenv

load_dotenv()

API = "https://fxmacrodata.com/api/v1"
KEY = os.environ["FXMD_API_KEY"]
CURRENCIES = ["usd", "eur", "gbp", "jpy", "aud", "cad", "chf", "nzd"]


def fxmd_get(path, **params):
    r = requests.get(
        f"{API}{path}",
        params={"api_key": KEY, **params},
        timeout=25,
    )
    r.raise_for_status()
    return r.json()


def upcoming_releases(hours_ahead: int = 24):
    now = datetime.now(timezone.utc)
    cutoff = now + timedelta(hours=hours_ahead)
    releases = []
    for ccy in CURRENCIES:
        try:
            data = fxmd_get(f"/calendar/{ccy}").get("data", [])
        except requests.HTTPError:
            continue
        for ev in data:
            try:
                ts = datetime.fromisoformat(
                    ev["announcement_datetime"].replace("Z", "+00:00")
                )
            except (KeyError, ValueError):
                continue
            if now <= ts <= cutoff:
                releases.append({
                    "currency": ccy.upper(),
                    "indicator": ev.get("indicator") or ev.get("name"),
                    "scheduled_utc": ts.isoformat(),
                    "prior": ev.get("prior_value"),
                    "consensus": ev.get("consensus") or ev.get("market_consensus"),
                    "importance": ev.get("importance") or ev.get("impact"),
                })
    releases.sort(key=lambda r: r["scheduled_utc"])
    return releases

Etapa 2: Classificação das publicações por impacto provável no mercado

Nem todas as impressões movem os mercados. Salarios não agrícolas- Não . PCE de base- Não . Taxa de política monetária- Não . IPC da área do euro- Não . IPC do Reino UnidoE ... Taxa de juro de política monetária do BoJ A economia de mercado é uma economia de pequena dimensão, mas a sua economia é muito mais dinâmica.

Codifica uma tabela de peso explícita para que o agente não tenha que adivinhar.

TIER_1 = {
    ("USD", "non_farm_payrolls"), ("USD", "core_pce"), ("USD", "policy_rate"),
    ("USD", "inflation"), ("USD", "fomc_minutes"),
    ("EUR", "inflation"), ("EUR", "policy_rate"),
    ("GBP", "inflation"), ("GBP", "policy_rate"),
    ("JPY", "policy_rate"), ("JPY", "inflation"),
    ("AUD", "policy_rate"), ("CAD", "policy_rate"),
    ("CHF", "policy_rate"), ("NZD", "policy_rate"),
}

TIER_2 = {
    ("USD", "retail_sales"), ("USD", "ism_manufacturing"),
    ("EUR", "gdp"), ("EUR", "unemployment"),
    ("GBP", "gdp"), ("GBP", "retail_sales"),
    ("AUD", "inflation"), ("CAD", "inflation"),
}


def impact_score(event: dict) -> int:
    key = (event["currency"], (event["indicator"] or "").lower())
    if key in TIER_1:
        return 3
    if key in TIER_2:
        return 2
    return 1


def rank(releases):
    return sorted(
        releases,
        key=lambda r: (-impact_score(r), r["scheduled_utc"]),
    )

Agora você pode colapsar o dia em uma lista estruturada onde os eventos de nível 1 aparecem primeiro independentemente do tempo UTC.


Passo 3: Adicione o contexto da noite para que o agente saiba o que já se moveu

Uma reunião matinal é incompleta sem um instantâneo dos movimentos do FX durante a noite.

PAIRS = [("USD", "JPY"), ("EUR", "USD"), ("GBP", "USD"), ("AUD", "USD")]


def overnight_moves():
    moves = []
    for base, quote in PAIRS:
        try:
            data = fxmd_get(
                "/forex",
                base=base,
                quote=quote,
            ).get("data", [])
        except requests.HTTPError:
            continue
        if len(data) < 2:
            continue
        last = data[-1]["value"]
        prev = data[-25]["value"] if len(data) >= 25 else data[0]["value"]
        change_pct = (last - prev) / prev * 100
        moves.append({
            "pair": f"{base}/{quote}",
            "last": round(last, 5),
            "change_pct_24h": round(change_pct, 2),
        })
    return moves

Se você também quiser contexto de posicionamento para os negócios swing, adicione um COT Mantenha-o opcional, o briefing ainda deve funcionar sem ele.


Passo 4: Gerar o briefing com um LLM

O agente agora tem três entradas estruturadas: eventos classificados, movimentos FX durante a noite e o carimbo de tempo UTC atual. Passe-os para o modelo com um contrato de saída rigoroso para que o briefing seja analisável e consistente todas as manhãs.

import json
from anthropic import Anthropic

claude = Anthropic(api_key=os.environ["ANTHROPIC_API_KEY"])

SYSTEM_PROMPT = """You are an FX morning-prep analyst.
Given today's ranked releases and overnight moves, produce a briefing that:
- leads with the single most important event of the day,
- groups events by impact tier,
- flags 1-2 specific pairs to watch and why,
- ends with one disciplined risk caveat.
Do not give buy/sell instructions. Stay factual. Max 220 words."""


def generate_briefing(events, moves):
    payload = json.dumps({
        "utc_now": datetime.now(timezone.utc).isoformat(),
        "ranked_events": events,
        "overnight_moves": moves,
    })
    resp = claude.messages.create(
        model="claude-3-5-sonnet-latest",
        max_tokens=600,
        system=SYSTEM_PROMPT,
        messages=[{"role": "user", "content": payload}],
    )
    return resp.content[0].text

Três coisas fazem este prompt confiável:

  • Entrada estruturada. O modelo recebe JSON, não linguagem natural, por isso nunca tem que extrair datas ou números do texto.
  • - O que é? O sistema proíbe recomendações de negociação, o que mantém a saída compatível e útil mesmo em dias voláteis.
  • - O limite de comprimento. 220 palavras forçam a densidade do sinal, longas reuniões treinam-nos para desfrutar, o que desvanta o propósito.

Passo 5: Entregue no Telegram (ou Slack)

O briefing tem de chegar onde já olhas logo de manhã.

def send_telegram(text: str):
    token = os.environ["TELEGRAM_BOT_TOKEN"]
    chat_id = os.environ["TELEGRAM_CHAT_ID"]
    requests.post(
        f"https://api.telegram.org/bot{token}/sendMessage",
        json={
            "chat_id": chat_id,
            "text": text,
            "parse_mode": "Markdown",
            "disable_web_page_preview": True,
        },
        timeout=15,
    )


def run():
    events = rank(upcoming_releases(hours_ahead=24))
    moves = overnight_moves()
    briefing = generate_briefing(events, moves)
    header = f"*FX Morning Briefing — {datetime.now(timezone.utc):%a %d %b %Y}*\n\n"
    send_telegram(header + briefing)


if __name__ == "__main__":
    run()

No Linux/macOS, uma única entrada crontab executa o agente todos os dias de semana às 06:30 UTC:

30 6 * * 1-5 /usr/bin/python3 /opt/fx-agent/morning_brief.py >> /var/log/fx-agent.log 2>&1

Como é que a reunião realmente se parece

Exemplo de saída do agente produzido numa semana recente do IPC:

FX Morning Briefing — Thu 22 May 2026

Today's anchor: US Core PCE at 12:30 UTC. Consensus 0.2% MoM,
prior 0.0%. A second sub-0.1 print would cement the disinflation
narrative; a 0.3+ surprise resets Fed pricing.

Tier 1:
- 12:30 UTC USD Core PCE  prior +0.0%  cons +0.2%
- 13:30 UTC USD Initial Jobless Claims  prior 228k  cons 225k

Tier 2:
- 06:00 UTC GBP Retail Sales MoM  prior -0.1%  cons +0.4%
- 09:00 UTC EUR ECB Minutes (qualitative)

Pairs to watch:
- USD/JPY hovering 158.40 after a quiet Asia. PCE miss → 156s
  back in play.
- GBP/USD coiled below 1.2700. Stronger UK retail + soft PCE is
  the cleanest setup of the day.

Risk caveat: thin EU liquidity ahead of US data; expect outsized
moves on any surprise print.

É uma leitura completa de pré-comercialização em menos de 90 segundos, todos os dias da semana, sem arrancar calendário manualmente.


Lista de verificação de endurecimento antes de confiar nela

  • Guarda de dados obsoleta. Recusar-se a enviar o briefing se qualquer evento de nível 1 não chegar a um horário programado.
  • Tente novamente com o back-off Três tentativas, 2s/4s/8s, depois falham em voz alta.
  • Validador de saída. Rejeite qualquer resposta de LLM que contenha as palavras "comprar", "vender" ou "longo" / "curto".
  • Alerta de batimento cardíaco. Se o agente não enviar um briefing até as 07:00 UTC, pinge-se separadamente para não perder silenciosamente o fluxo de trabalho.
  • - O limite de custos. - Está pronto . max_tokens=600 As reuniões devem custar centavos por dia.

Para onde a levar agora?

O mesmo andaime se estende facilmente quando o loop da manhã é confiável:

  • Alertas surpreendentes intradiárias. Pesquisa . Anúncios pontos finais A cada 15 minutos após uma liberação de nível 1; alerta quando a situação real diverge do consenso em mais do que o seu limiar.
  • Informes específicos para pares. Gerencie um mais apertado . USD/JPY- Só ou... EUR/USD- apenas versão para dias ativos.
  • - Posicionamento de sobreposição. Puxa . Dados COT Semanal e alimentá-lo no mesmo prompt para que o briefing sabe quando o mercado é unilateral.
  • Modo de voz. Envia o briefing através de um modelo TTS e lê-o em voz alta enquanto preparas café.

A vitória não é o briefing em si, é o contexto disciplinado e reproduzível com o qual você entra em seu dia de negociação.

Blogroll