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

كيفية استخدام FXMacroData API مع Go

دليل خطوة بخطوة للاتصال بـ FXMacroData REST API من Go يغطي إعداد net/http client ، والتحقق من صحة معايير الاستعلامات ، وتشفير JSON ، ومساعدين قابلة لإعادة الاستخدام للإعلانات ، وعادة الإصدارات ، وأسعار الفورية في العملات الأجنبية.

متوفر أيضًا في English
Share article X LinkedIn Email

يعد Go شائعًا بشكل متزايد للأدوات المالية إن تجميعه السريع وأدائه المتوقع وأصوله الأولية المتزامنة من الدرجة الأولى تجعله مناسبًا طبيعيًا لخطوط أنابيب البيانات وأتمتة التداول. يمر هذا الدليل بكل ما تحتاجه للاتصال بـ FXMacroData REST API من Go ، من طلب بسيط لمرة واحدة إلى عميل قابل لإعادة الاستخدام يتعامل مع المدة النهائية ، فك تشفير JSON ، وتصفية التاريخ الاختيارية. بحلول النهاية سيكون لديك رمز Go لغوي يسترد إعلانات مؤشر الماكرو ، ويسحب تقويم الإصدار القادم ، ويسأل أسعار الفوركس كل ذلك في أقل من 150 سطر.

ما الذي ستبنيه

عميل HTTP خفيف الوزن يُصادق على API REST FXMacroData باستخدام إصدار أساس API معين ، ويقوم بتفكيك استجابات JSON المنظمة إلى هياكل Go المطبوعة ، ويكشف عن وظائف مساعد قابلة لإعادة الاستخدام لثلاث عائلات النقاط النهائية الأكثر شيوعًا: الإعلانات وتقويم الإصدار ومعدلات الفورية FX.

الشروط المسبقة

  • الذهاب 1.21 أو أحدث (go.dev/dl)
  • مفتاح FXMacroData API تسجيل في / اشترك لتلقي واحدة
  • معرفة أساسية بوحدة غو والمكتبة القياسية

لا حاجة إلى مكتبات HTTP أو JSON من طرف ثالث المعيار net/http و encoding/json الحزم تتعامل مع كل شيء

الخطوة 1 فهم شكل API

كل نقطة نهاية مؤشر FXMacroData تتبع نمط URL نفسه:

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

الرد هو كائن JSON مع مستوى أعلى data كل عنصر يحتوي على date سلسلة، رقمية valو إختيارياً announcement_datetime هذا يعطي دقة من المستوى الثاني عندما تم إصدار الرقم رسمياً. على سبيل المثال:

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" }
  ]
}

تنطبق نفس هيكل المغلف على نقاط النهاية التقويمية والفوركس، مما يجعل من السهل كتابة رمز فك عام واحد وتخصص أنواع نقطة النهاية الواحدة فوقها.

الخطوة 2 بدء تشغيل الوحدة

إنشاء دليل جديد للمشروع وبدء وحدة الذهاب:

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

يمكنك تخزين مفتاح API الخاص بك في متغير البيئة بدلاً من ترميزه بصورة صارمة. يمكنك تصديره للجلسة الحالية للشيل:

export FXMD_API_KEY="your_actual_api_key_here"

نصيحة أمنية

لا تقم أبداً بتشفير مفاتيح API في ملفات المصدر أو إلتزامها بمراقبة الإصدارات. في الإنتاج ، استخدم مدير أسرار أو متغير بيئة CI / CD. ينظر النمط المعروض هنا إلى المفتاح عند بدء التشغيل ويفشل بسرعة إذا كان المتغير مفقودًا.

الخطوة 3 تحديد أنواع الاستجابة

أنشئ ملفًا يدعى fxmd.go. ابدأ بتعريف هيكل Go الذي يرسله إلى أشكال JSON التي تعودها عائلات النقاط النهائية الثلاث التي ستستخدمها:

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"`
}

الخطوة 4 بناء عميل قابلة لإعادة الاستخدام

لفاف رقيق حولها net/http يبقي boilerplate خارج رمز الدعوة. يقرأ العميل مفتاح API مرة واحدة في البناء، ويحقنه كمعلم استفسار في كل طلب، ويفرض وقتًا نهائيًا بحيث لا يمكن أن يؤخر البرنامج الخاص بك إلى أجل غير مسمى:

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

باستخدام json.NewDecoder على جسم الاستجابة (بدلاً من قراءة الجسم إلى شريحة بايت أولاً) هو النهج المفرد في Go: إنه يسلط فك الترميز مباشرة من اتصال HTTP ، وتجنب تخصيصًا وسيطًا للحمولات الضخمة.

الخطوة 5 إضافة مساعدات مطبوعة لكل عائلة نقطة نهاية

لفّي العقار get طريقة مع مساعدي المكتوب حتى لا يتعين على المتصلين بناء مسارات أو فك شفرة المظروف يدوياً:

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

الخطوة 6 ضعي كل شيء معاً main

مع العميل والمساعدين في مكانهم، استدعاء واجهة برمجة التطبيقات هو موجزة وآمنة النوع. main وظيفة إلى fxmd.go التي تمارس كل ثلاث عائلات من النقاط النهائية:

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

اطلق البرنامج

go run fxmd.go

يجب أن ترى مخرجات مشابهة ل:

=== 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

نصيحة الحملات المشتركة مع الجوروتين

لأن العميل آمن للاستخدام المتزامن، يمكنك نشر طلبات مؤشر متعددة بالتوازي باستخدام الروتينات sync.WaitGroup أو errgroupهذا مفيد بشكل خاص عند بناء لوحة تحكم تسحب عدة عملات في وقت واحد الوقت الساعة الجدار يبقى بالقرب من فترة تأخير بطيئة الطلب الواحد بدلا من مجموع جميع الطلبات.

الخطوة 7 التعامل مع صفحة وتفاصيل التاريخ

بشكل افتراضي، نقطة نهاية الإعلانات تعيد كل التاريخ المتاح. المعروض النقدي في م2 أو الناتج المحلي الإجمالي سوف ترغب في الحد من نافذة استخدام start و end معايير الاستفسار كلا المساعدين يدعمونها بالفعل. هنا مثال مركز يحصل فقط على الربع الأخير من العمل بدوام جزئي في الولايات المتحدة البيانات:

// 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)
}

‬ ‫القياس time صيغ الحزمة "2006-01-02" (الوقت المرجعي هو التذكر: 01/02 03:04:05 PM '06 -0700) ، والذي يتطابق مع سلسلة التواريخ ISO-8601 المتوقعة من قبل API.

الخطوة 8 تحليل announcement_datetime كـ time.Time

- ... announcement_datetime المجال هو سلسلة UTC RFC-3339. إذا كان تطبيقك يحتاج إلى حساب العد التنازلي للوقت إلى الإفراج أو فرز الأحداث أو بيانات الدلو حسب الجلسة ، فقم بتحليلها إلى time.Time القيمة:

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

قائمة الملفات الكاملة

للمرجع، هنا تنفيذ الملف الواحد الكامل الموصوف في الخطوات أعلاه:

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

ما التالي

لديك الآن عميل Go يعمل يغطي ثلاثة أسرة من نقاط نهاية FXMacroData الأكثر شيوعاً.

  • توسيع تعريفات الهيكل لالتقاط حقول إضافية مثل revised القيم من نقطة نهاية التقويم.
  • إضافة errgroup-بناء على المروحة لتحقيق عملات متعددة في وقت واحد Client من الآمن أن تشارك بين الروتينات لأن http.Client هو آمن من التزامن من خلال التصميم.
  • استمرار النتائج إلى قاعدة بيانات SQLite المحلية باستخدام database/sql للاختبار الخلفي الخفيف أو أبحاث الإشارات.
  • استكشاف الكتالوج الكامل للمؤشرات للدولار الأمريكي عند /api-data-docs/USD/الأجور وبالنسبة للعملات الأخرى عبر لوحة القيادة ابحث عن م2- لا العمل بدوام جزئيو الناتج المحلي الإجمالي كنقاط انطلاق نظراً لإشارات الطلب التي دفعت هذا الدليل.

Blogroll

AI Answer-Ready

Key Facts

Page
How To Use The FXmacrodata API With Go
Section
Articles
Canonical URL
https://fxmacrodata.com/articles/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.

Share page X LinkedIn Email