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.

Disponible también en English

¿Por qué un agente de preparación de la mañana es el robot de mayor retorno de la inversión que puedes construir primero?

Si usted opera FX discrecionalmente o ejecuta un libro semiautomático, los 45 minutos más caros de su día son los que antes de que Londres abra. calendario de liberación, comprobar qué huellas son de primer nivel, buscar consenso, escanear movimientos de la noche a la mañana El valor de las pérdidas¿ Qué ? El valor de la moneda de referencia¿ Qué ? El valor de las pérdidasEs repetitivo, propenso a errores, y te obliga a reconstruir el contexto cada mañana desde cero.

Este es exactamente el tipo de tarea que un agente de IA hace mejor que un humano: alcance limitado, entradas estructuradas, salida determinista. agente de eventos de divisas en tiempo real que se ejecuta antes de su día de negociación, extrae datos de eventos en vivo de FXMacroData, clasifica los lanzamientos de hoy por el impacto probable del mercado, y ofrece un informe estructurado que puede leer en 90 segundos.

Al final tendrás un script que puedes programar en cualquier máquina laptop, Raspberry Pi, nube VM que convierte la preparación de la mañana de una tarea en una lista de verificación.

Lo que construirás
Un agente de Python que se ejecuta a las 06:30 UTC diariamente, consulta el calendario de lanzamiento de FXMacroData para las próximas 24 horas en todo el G10, clasifica los eventos por impacto, los resume a través de un LLM y envía una sesión informativa estructurada a Telegram o Slack.

Los requisitos previos

  • Python 3.10+ y pip.
  • Una clave de la API de FXMacroData de Gestión de las API- ¿ Qué ?
  • Un punto final de LLM que usted controla.
    • Claude antrópico (recomendado para la calidad del razonamiento).
    • OpenAI GPT-4 de clase.
    • Hermes/Llama local a través de Ollama para vuelos de costo cero.
  • Un bot de Telegram con token (a través de @BotFather) o una URL de webhook entrante de Slack funciona como el canal de entrega.
  • Un programador. cron en Linux/macOS, el Programador de tareas en Windows, o cualquier cron en la nube lo hará.

Instalar dependencias:

pip install requests python-dotenv

Crear un .env archivo con sus secretos:

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

Paso 1: extraer las próximas 24 horas del calendario de liberación de FXMacroData

El primer trabajo del agente es saber lo que está realmente programado. FXMacroData también el calendario de lanzamiento de los resultados de los puntos finales de las emisiones programadas por moneda, incluido el nombre del indicador, la hora de fecha UTC programada, el valor anterior y la clasificación de importancia, cuando estén disponibles.

Buscarlo para cada moneda principal que usted comercio:

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"

Envuelva esto en Python para que el agente pueda iterar a través de una lista de divisas configurable:

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

Paso 2: Clasificación de las publicaciones por impacto probable en el mercado

No todas las impresiones mueven los mercados. Pago de los trabajadores no agrícolas¿ Qué ? PCE de base¿ Qué ? Tasa de política de la Fed¿ Qué ? el IPC de la zona del euro¿ Qué ? IPC del Reino Unido, y Tasa de interés de política monetaria del Banco de Japón El comercio minorista en una economía menor rara vez importa.

Encódense una tabla de peso explícita para que el agente no tenga que adivinar.

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"]),
    )

Ahora puedes agrupar el día en una lista estructurada donde los eventos de nivel 1 aparecen primero independientemente del tiempo UTC.


Paso 3: Añadir contexto durante la noche para que el agente sepa lo que ya se movió

Una sesión informativa matutina no está completa sin una instantánea de los movimientos de divisas durante la noche.

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

Si también desea el contexto de posicionamiento para las operaciones de swing, añadir un El COT Mantenga la opción de que la reunión funcione sin él.


Paso 4: Generar el informe con un LLM

El agente ahora tiene tres entradas estructuradas: eventos clasificados, movimientos de divisas durante la noche y la marca de tiempo UTC actual. Pasa en el modelo con un contrato de salida estricto para que el informe sea analizable y consistente todas las mañanas.

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

Tres cosas hacen que este aviso sea confiable:

  • Entrada estructurada. El modelo recibe JSON, no lenguaje natural, por lo que nunca tiene que extraer fechas o números del texto.
  • Espejo duro. El sistema prohíbe las recomendaciones comerciales, lo que mantiene la salida compatible y útil incluso en días volátiles.
  • El límite de longitud. 220 palabras forzan la densidad de señal, largas sesiones te entrenan para deslumbrar, lo que derrota el propósito.

Paso 5: Envíe a Telegram (o Slack)

La sesión informativa tiene que aterrizar donde ya lo ves a primera hora de la mañana.

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()

En Linux/macOS, una sola entrada crontab ejecuta el agente todos los días de la semana a las 06:30 UTC:

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

Cómo es la reunión

Ejemplo de salida del agente producido en una semana reciente de 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.

Eso es una lectura completa de pre-mercado en menos de 90 segundos, todos los días de la semana, sin raspado manual del calendario.


Una lista de verificación de endurecimiento antes de confiar en ella

  • Guardia de datos obsoleta. Rechazar el envío de la información si algún evento de nivel 1 falta en un tiempo programado.
  • Vuelva a intentar con el respaldo Tres intentos, 2s/4s/8s, luego falla en voz alta.
  • Validador de salida. Rechazar cualquier respuesta LLM que contenga las palabras "comprar", "vender", o "largo" / "corto".
  • Alerta de latidos cardíacos. Si el agente no envía una sesión informativa antes de las 07:00 UTC, píngase por separado para no perder silenciosamente el flujo de trabajo.
  • El límite de costos. Ya está . max_tokens=600 Las reuniones deberían costar centavos por día.

¿Dónde llevarlo ahora?

El mismo andamio se extiende fácilmente una vez que el bucle de la mañana es confiable:

  • Alertas de sorpresa durante el día. Encuesta Puntos finales de anuncios cada 15 minutos después de una liberación de nivel 1; alerta cuando la realidad se desvíe del consenso en más de su umbral.
  • Informes específicos para parejas. Generar un más apretado El valor de las pérdidas- Sólo o... El valor de la moneda de referencia- sólo versión para días activos.
  • Posicionamiento de superposición. Tirad . Datos de la COT semanales y lo alimentan en el mismo aviso para que el informe sepa cuándo el mercado es unilateral.
  • Modo de voz. Envía la sesión informativa a través de un modelo TTS y haz que la lean en voz alta mientras haces el café.

La victoria no es el briefing en sí, es el contexto disciplinado y reproducible con el que entras en tu día de trading.

Blogroll