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
Wie wird die FXMacroData API mit Go verwendet? image
Share headline card X LinkedIn Email
Download

Implementation

How-To Guides

Wie wird die FXMacroData API mit Go verwendet?

Ein Schritt-für-Schritt-Leitfaden zum Aufrufen der FXMacroData REST API von Go abdeckend net/http Client-Setup, Abfrage-Parameter-Authentifizierung, JSON-Decodierung und wiederverwendbare Helfer für Ankündigungen, den Release-Kalender und FX-Spot-Raten.

Auch verfügbar auf English
Share article X LinkedIn Email

Go ist zunehmend beliebt für Finanzwerkzeuge seine schnelle Kompilierung, vorhersehbare Leistung und erstklassige Gleichzeitigkeit Primitive machen es zu einem natürlichen Passform für Datenpipelines und Handelsautomation. Dieser Leitfaden geht durch alles, was Sie benötigen, um die FXMacroData REST API von Go aufzurufen, von einer einfachen einmaligen Anfrage bis zu einem wiederverwendbaren Client, der Timeouts, JSON-Decodierung und optionales Datum Filtern verarbeitet. Am Ende haben Sie idiomatischen Go-Code, der Makro-Indikatorankündigungen abruft, einen Kalender für die bevorstehende Veröffentlichung zieht und FX-Spotraten in weniger als 150 Zeilen abfragt.

Was du bauen wirst

Ein leichter Go HTTP-Client, der sich mit der FXMacroData REST API mit Hilfe des Abfrageparameters API-Key-Auth authentifiziert, strukturierte JSON-Antworten in getypte Go-Strukturen dekodiert und wiederverwendbare Helferfunktionen für die drei häufigsten Endpunktfamilien zeigt: Ankündigungen, Release-Kalender und FX-Spotraten.

Voraussetzungen

Es werden keine HTTP- oder JSON-Bibliotheken von Drittanbietern benötigt der Standard net/http Und ... encoding/json Die Pakete regeln alles.

Schritt 1 Die API-Form verstehen

Jeder Endpunkt des FXMacroData-Indikators folgt demselben URL-Muster:

GET https://fxmacrodata.com/api/v1/announcements/{currency}/{indicator}?api_key=YOUR_API_KEY

Die Antwort ist ein JSON-Objekt mit einem oberen Level data Jedes Element enthält eine date Eine Zeichenfolge, eine Zahl. val, und optional eine announcement_datetime Das gibt eine zweite Präzision für das Datum, an dem die Zahl offiziell veröffentlicht wurde.

curl "https://fxmacrodata.com/api/v1/announcements/usd/wages?api_key=YOUR_API_KEY&start=2024-01-01"
{
  "data": [
    { "date": "2025-03-14", "val": 4.0, "announcement_datetime": "2025-03-14T12:30:00Z" },
    { "date": "2025-02-07", "val": 4.1, "announcement_datetime": "2025-02-07T13:30:00Z" },
    { "date": "2025-01-10", "val": 3.9, "announcement_datetime": "2025-01-10T13:30:00Z" }
  ]
}

Die gleiche Umschlagstruktur gilt für die Kalender- und Forex-Endpunkte, wodurch es einfach ist, einen einzelnen generischen Decoder zu schreiben und spezialisierte Endpunkte zu schreibt.

Schritt 2 Ihr Modul initialisieren

Erstellen Sie ein neues Verzeichnis für das Projekt und initialisieren Sie ein Go-Modul:

mkdir fxmd-go && cd fxmd-go
go mod init fxmd

Speichern Sie Ihren API-Schlüssel in einer Umgebungsvariable, anstatt ihn hart zu kodieren.

export FXMD_API_KEY="your_actual_api_key_here"

Sicherheitstipp

Verwenden Sie niemals Hardcode-API-Schlüssel in Quelldateien oder verpflichten Sie sie zur Versionskontrolle. In der Produktion verwenden Sie einen Geheimnismanager oder eine CI / CD-Umgebungsvariable. Das hier gezeigte Muster liest den Schlüssel beim Starten und versagt schnell, wenn die Variable fehlt.

Schritt 3 Definition von Reaktionsarten

Erstellen Sie eine Datei namens fxmd.go. Beginnen Sie mit der Definition der Go-Strukturen , die die von den drei verwendeten Endpunktfamilien zurückgegebenen JSON-Formen abbilden:

package main

import (
	"encoding/json"
	"fmt"
	"io"
	"net/http"
	"net/url"
	"os"
	"time"
)

const baseURL = "https://fxmacrodata.com/api/v1"

// DataPoint represents a single indicator observation.
type DataPoint struct {
	Date                string  `json:"date"`
	Val                 float64 `json:"val"`
	AnnouncementDatetime string  `json:"announcement_datetime,omitempty"`
}

// AnnouncementsResponse is the envelope for indicator announcement endpoints.
type AnnouncementsResponse struct {
	Data []DataPoint `json:"data"`
}

// CalendarEvent represents one upcoming or recent release on the calendar.
type CalendarEvent struct {
	Date      string  `json:"date"`
	Indicator string  `json:"indicator"`
	Expected  float64 `json:"expected,omitempty"`
	Prior     float64 `json:"prior,omitempty"`
	Actual    float64 `json:"actual,omitempty"`
}

// CalendarResponse is the envelope for the release calendar endpoint.
type CalendarResponse struct {
	Data []CalendarEvent `json:"data"`
}

// ForexPoint represents a single FX spot-rate observation.
type ForexPoint struct {
	Date string  `json:"date"`
	Rate float64 `json:"rate"`
}

// ForexResponse is the envelope for the FX spot-rate endpoint.
type ForexResponse struct {
	Data []ForexPoint `json:"data"`
}

Schritt 4 Erstellen Sie einen wiederverwendbaren Client

Eine dünne Umhüllung . net/http Der Client liest den API-Schlüssel einmal beim Bau, injiziert ihn als Abfrageparameter bei jeder Anfrage und erzwingt einen Timeout, so dass ein langsamer Upstream Ihr Programm nie unbegrenzt stoppen kann:

// Client is a lightweight FXMacroData API client.
type Client struct {
	apiKey     string
	httpClient *http.Client
}

// NewClient creates a Client that reads the API key from the FXMD_API_KEY environment variable.
// It panics at startup if the variable is not set — fail-fast is safer than silent empty results.
func NewClient() *Client {
	key := os.Getenv("FXMD_API_KEY")
	if key == "" {
		panic("FXMD_API_KEY environment variable is not set")
	}
	return &Client{
		apiKey: key,
		httpClient: &http.Client{
			Timeout: 15 * time.Second,
		},
	}
}

// get performs a GET request to the given path with optional query parameters.
// It decodes the JSON body into dest.
func (c *Client) get(path string, params url.Values, dest any) error {
	if params == nil {
		params = url.Values{}
	}
	params.Set("api_key", c.apiKey)

	u := baseURL + path + "?" + params.Encode()
	resp, err := c.httpClient.Get(u)
	if err != nil {
		return fmt.Errorf("http get %s: %w", path, err)
	}
	defer resp.Body.Close()

	if resp.StatusCode != http.StatusOK {
		body, _ := io.ReadAll(resp.Body)
		return fmt.Errorf("api error %d on %s: %s", resp.StatusCode, path, body)
	}

	if err := json.NewDecoder(resp.Body).Decode(dest); err != nil {
		return fmt.Errorf("json decode %s: %w", path, err)
	}
	return nil
}

- Ich benutze ... json.NewDecoder Die Verwendung von "Dicoding" auf dem Antwortkörper (anstatt den Körper zuerst in ein Byte-Slice zu lesen) ist der idiomatische Ansatz in Go: Es streamt die Entschlüsselung direkt von der HTTP-Verbindung aus und vermeidet eine Zwischenzuweisung für große Nutzlasten.

Schritt 5 Für jede Endpunktfamilie Typ-Hilfen hinzufügen

Verpacken Sie das Generikum . get Methode mit eingegebenem Helfer, so dass Anrufer niemals manuell Wege oder Decodierung von Umschlägen erstellen müssen:

// GetAnnouncements retrieves indicator announcement data for the given currency and indicator slug.
// start and end are optional date strings in "YYYY-MM-DD" format; pass "" to omit them.
//
// Example: client.GetAnnouncements("usd", "wages", "2024-01-01", "")
// Full indicator catalogue: https://fxmacrodata.com/api-data-docs/usd/wages
func (c *Client) GetAnnouncements(currency, indicator, start, end string) (*AnnouncementsResponse, error) {
	params := url.Values{}
	if start != "" {
		params.Set("start", start)
	}
	if end != "" {
		params.Set("end", end)
	}
	var out AnnouncementsResponse
	err := c.get("/announcements/"+currency+"/"+indicator, params, &out)
	return &out, err
}

// GetCalendar retrieves the upcoming release calendar for the given currency code.
//
// Example: client.GetCalendar("usd")
func (c *Client) GetCalendar(currency string) (*CalendarResponse, error) {
	var out CalendarResponse
	err := c.get("/calendar/"+currency, nil, &out)
	return &out, err
}

// GetForex retrieves FX spot-rate history for a currency pair.
// start and end are optional date strings in "YYYY-MM-DD" format.
//
// Example: client.GetForex("eur", "usd", "2024-01-01", "")
func (c *Client) GetForex(base, quote, start, end string) (*ForexResponse, error) {
	params := url.Values{}
	if start != "" {
		params.Set("start", start)
	}
	if end != "" {
		params.Set("end", end)
	}
	var out ForexResponse
	err := c.get("/forex/"+base+"/"+quote, params, &out)
	return &out, err
}

Schritt 6 Wirf alles zusammen main

Mit dem Client und Helfern ist der Anruf der API prägnant und typschutzsicher. main Funktion zu fxmd.go die alle drei Endpunktfamilien ausübt:

func main() {
	client := NewClient()

	// --- Announcements: US wages ---
	fmt.Println("=== US Wages (last 5 releases) ===")
	wages, err := client.GetAnnouncements("usd", "wages", "2024-01-01", "")
	if err != nil {
		fmt.Println("error:", err)
	} else {
		for i, pt := range wages.Data {
			if i >= 5 {
				break
			}
			fmt.Printf("  %s  val=%.2f  released=%s\n", pt.Date, pt.Val, pt.AnnouncementDatetime)
		}
	}

	// --- Release calendar: upcoming USD events ---
	fmt.Println("\n=== Upcoming USD Releases ===")
	cal, err := client.GetCalendar("usd")
	if err != nil {
		fmt.Println("error:", err)
	} else {
		for i, ev := range cal.Data {
			if i >= 5 {
				break
			}
			fmt.Printf("  %s  %s  prior=%.2f  expected=%.2f\n",
				ev.Date, ev.Indicator, ev.Prior, ev.Expected)
		}
	}

	// --- FX spot rates: EUR/USD ---
	fmt.Println("\n=== EUR/USD Spot Rate (last 5 days) ===")
	fx, err := client.GetForex("eur", "usd", "2025-01-01", "")
	if err != nil {
		fmt.Println("error:", err)
	} else {
		for i, pt := range fx.Data {
			if i >= 5 {
				break
			}
			fmt.Printf("  %s  rate=%.5f\n", pt.Date, pt.Rate)
		}
	}
}

Führen Sie das Programm aus:

go run fxmd.go

Sie sollten eine Ausgabe sehen, die ähnlich ist wie:

=== US Wages (last 5 releases) ===
  2025-03-14  val=4.00  released=2025-03-14T12:30:00Z
  2025-02-07  val=4.10  released=2025-02-07T13:30:00Z
  2025-01-10  val=3.90  released=2025-01-10T13:30:00Z
  2024-12-06  val=4.00  released=2024-12-06T13:30:00Z
  2024-11-01  val=4.00  released=2024-11-01T12:30:00Z

=== Upcoming USD Releases ===
  2025-04-25  gdp  prior=2.30  expected=0.40
  2025-05-02  non_farm_payrolls  prior=228.00  expected=135.00
  2025-05-13  inflation  prior=2.40  expected=2.30

=== EUR/USD Spot Rate (last 5 days) ===
  2025-04-17  rate=1.13452
  2025-04-16  rate=1.13680
  2025-04-15  rate=1.13590
  2025-04-14  rate=1.13320
  2025-04-11  rate=1.13580

Tipp Gleichzeitige Abholungen mit Goroutines

Da der Client sicher für gleichzeitige Verwendung ist, können Sie mehrere Indikator-Anfragen parallel mit goroutines und sync.WaitGroup Oder ... errgroup. Dies ist besonders nützlich, wenn Sie ein Dashboard erstellen, das mehrere Währungen gleichzeitig zieht die Wanduhrzeit bleibt in der Nähe der Latenzzeit der langsamsten einzelnen Anfrage und nicht der Summe aller Anfragen.

Schritt 7 Verarbeiten von Seitenbezeichnung und Datumsbereichen

Standardmäßig gibt der Endpunkt für Ankündigungen alle verfügbaren Daten zurück. M2 Geldmenge Oder ... BIP Sie werden oft wollen, das Fenster zu begrenzen, indem Sie start Und ... end Hier ist ein fokussiertes Beispiel, das nur das jüngste Quartal von Teilzeitbeschäftigung in den USA Daten:

// Fetch US part-time employment for the last 90 days
end := time.Now().Format("2006-01-02")
start := time.Now().AddDate(0, 0, -90).Format("2006-01-02")

pt, err := client.GetAnnouncements("usd", "part_time_employment", start, end)
if err != nil {
    log.Fatal(err)
}
for _, dp := range pt.Data {
    fmt.Printf("%s  %.0f\n", dp.Date, dp.Val)
}

Das ist Go's Standard. time Daten zu den Paketformaten "2006-01-02" (Die Referenzzeit ist eine Mnemonik: 01/02 03:04:05 PM '06 -0700), die mit den von der API erwarteten ISO-8601-Datenzfolgen übereinstimmt.

Schritt 8 Parsieren announcement_datetime als time.Time

Die ... announcement_datetime Das Feld ist eine UTC RFC-3339-String. Wenn Ihre Anwendung Zeit-zu-Veröffentlichung Countdowns berechnen, Ereignisse sortieren oder Bucket-Daten nach Sitzung benötigt, analysieren Sie es in eine time.Time Wert:

const rfc3339 = time.RFC3339

for _, dp := range wages.Data {
    if dp.AnnouncementDatetime == "" {
        continue
    }
    t, err := time.Parse(rfc3339, dp.AnnouncementDatetime)
    if err != nil {
        log.Printf("bad datetime %q: %v", dp.AnnouncementDatetime, err)
        continue
    }
    until := time.Until(t)
    fmt.Printf("%s  val=%.2f  in %s\n", dp.Date, dp.Val, until.Round(time.Minute))
}

Vollständige Datei-Liste

Hier ist die vollständige Einfachdatei-Implementierung, die in den oben genannten Schritten beschrieben wird:

package main

import (
	"encoding/json"
	"fmt"
	"io"
	"net/http"
	"net/url"
	"os"
	"time"
)

const baseURL = "https://fxmacrodata.com/api/v1"

type DataPoint struct {
	Date                string  `json:"date"`
	Val                 float64 `json:"val"`
	AnnouncementDatetime string  `json:"announcement_datetime,omitempty"`
}

type AnnouncementsResponse struct {
	Data []DataPoint `json:"data"`
}

type CalendarEvent struct {
	Date      string  `json:"date"`
	Indicator string  `json:"indicator"`
	Expected  float64 `json:"expected,omitempty"`
	Prior     float64 `json:"prior,omitempty"`
	Actual    float64 `json:"actual,omitempty"`
}

type CalendarResponse struct {
	Data []CalendarEvent `json:"data"`
}

type ForexPoint struct {
	Date string  `json:"date"`
	Rate float64 `json:"rate"`
}

type ForexResponse struct {
	Data []ForexPoint `json:"data"`
}

type Client struct {
	apiKey     string
	httpClient *http.Client
}

func NewClient() *Client {
	key := os.Getenv("FXMD_API_KEY")
	if key == "" {
		panic("FXMD_API_KEY environment variable is not set")
	}
	return &Client{
		apiKey: key,
		httpClient: &http.Client{Timeout: 15 * time.Second},
	}
}

func (c *Client) get(path string, params url.Values, dest any) error {
	if params == nil {
		params = url.Values{}
	}
	params.Set("api_key", c.apiKey)
	u := baseURL + path + "?" + params.Encode()
	resp, err := c.httpClient.Get(u)
	if err != nil {
		return fmt.Errorf("http get %s: %w", path, err)
	}
	defer resp.Body.Close()
	if resp.StatusCode != http.StatusOK {
		body, _ := io.ReadAll(resp.Body)
		return fmt.Errorf("api error %d on %s: %s", resp.StatusCode, path, body)
	}
	return json.NewDecoder(resp.Body).Decode(dest)
}

func (c *Client) GetAnnouncements(currency, indicator, start, end string) (*AnnouncementsResponse, error) {
	params := url.Values{}
	if start != "" { params.Set("start", start) }
	if end != ""   { params.Set("end",   end)   }
	var out AnnouncementsResponse
	return &out, c.get("/announcements/"+currency+"/"+indicator, params, &out)
}

func (c *Client) GetCalendar(currency string) (*CalendarResponse, error) {
	var out CalendarResponse
	return &out, c.get("/calendar/"+currency, nil, &out)
}

func (c *Client) GetForex(base, quote, start, end string) (*ForexResponse, error) {
	params := url.Values{}
	if start != "" { params.Set("start", start) }
	if end != ""   { params.Set("end",   end)   }
	var out ForexResponse
	return &out, c.get("/forex/"+base+"/"+quote, params, &out)
}

func main() {
	client := NewClient()

	wages, err := client.GetAnnouncements("usd", "wages", "2024-01-01", "")
	if err != nil {
		fmt.Println("wages error:", err)
	} else {
		fmt.Println("=== US Wages ===")
		for i, pt := range wages.Data {
			if i >= 5 { break }
			fmt.Printf("  %s  %.2f\n", pt.Date, pt.Val)
		}
	}

	cal, err := client.GetCalendar("usd")
	if err != nil {
		fmt.Println("calendar error:", err)
	} else {
		fmt.Println("=== Upcoming USD Releases ===")
		for i, ev := range cal.Data {
			if i >= 5 { break }
			fmt.Printf("  %s  %s\n", ev.Date, ev.Indicator)
		}
	}

	fx, err := client.GetForex("eur", "usd", "2025-01-01", "")
	if err != nil {
		fmt.Println("forex error:", err)
	} else {
		fmt.Println("=== EUR/USD ===")
		for i, pt := range fx.Data {
			if i >= 5 { break }
			fmt.Printf("  %s  %.5f\n", pt.Date, pt.Rate)
		}
	}
}

Was kommt als Nächstes?

Sie haben nun einen funktionierenden Go-Client, der die drei häufigsten FXMacroData-Endpunktfamilien abdeckt.

  • Erweiterung der Strukturdefinitionen um zusätzliche Felder wie revised Werte ab dem Kalenderendpunkt.
  • Fügen Sie ein errgroup- auf der Grundlage von Fan-Out - um mehrere Währungen gleichzeitig abzurufen die Client ist sicher, über goroutines zu teilen, weil http.Client ist gleichzeitig sicher.
  • Folgen Sie den Ergebnissen in einer lokalen SQLite-Datenbank verwenden database/sql für leichte Rückprüfung oder Signalforschung.
  • Siehe vollständiger Indikatorkatalog für USD bei /api-data-docs/USD/Löhne und für andere Währungen auf dem Dashboard suchen Sie nach M2- Ich weiß . TeilzeitbeschäftigungUnd ... BIP Die Kommission hat die Kommission aufgefordert, die in diesem Leitfaden beschriebenen Anwendungsbedingungen für die

Blogroll

AI Answer-Ready

Key Facts

Page
How To Use The FXmacrodata API With Go
Section
Articles
Canonical URL
https://fxmacrodata.com/de/artikel/how-to-use-the-fxmacrodata-api-with-go
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 The FXmacrodata API With Go 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.