गो वित्तीय टूलींग के लिए तेजी से लोकप्रिय है इसकी तेज़ संकलन, अनुमानित प्रदर्शन और प्रथम श्रेणी के समवर्ती आदिम इसे डेटा पाइपलाइन और ट्रेडिंग स्वचालन के लिए एक प्राकृतिक फिट बनाते हैं। यह गाइड आपको एक साधारण एक बार अनुरोध से एक पुनः प्रयोज्य क्लाइंट तक, जो टाइमआउट, जेएसओएन डिकोडिंग और वैकल्पिक तिथि फ़िल्टरिंग को संभालता है, गो से एफएक्समैक्रोडाटा आरईएसटी एपीआई को कॉल करने के लिए आवश्यक सब कुछ चलाता है। अंत तक आपके पास मुहावरागत गो कोड होगा जो मैक्रो संकेतक घोषणाओं को प्राप्त करता है, आगामी रिलीज कैलेंडर खींचता है और 150 से कम लाइनों में एफएक्स स्पॉट दरों को क्वेरी करता है।
आप क्या बनाएंगे
एक हल्का वजन वाला गो HTTP क्लाइंट जो क्वेरी-पैरामीटर एपीआई-की ऑथ का उपयोग करके एफएक्समैक्रोडाटा आरईएसटी एपीआइ के खिलाफ प्रमाणित करता है, टाइप किए गए गो स्ट्रक्चर में संरचित जेएसओएन प्रतिक्रियाओं को डिकोड करता है और तीन सबसे आम एंडपॉइंट परिवारों के लिए पुनः प्रयोज्य सहायक कार्यों को उजागर करता हैः घोषणाएं, रिलीज कैलेंडर और एफएक्स स्पॉट दरें।
पूर्व शर्तें
- जा 1.21 या बाद में स्थापित (go.dev/dl)
- एक FXMacroData एपीआई कुंजी पर साइन अप करें /अपना नाम लिखें प्राप्त करना
- गो मॉड्यूल और मानक पुस्तकालय के साथ बुनियादी परिचितता
कोई तृतीय पक्ष HTTP या JSON पुस्तकालयों की आवश्यकता नहीं है मानक net/http और
encoding/json पैकेज सब कुछ संभाल.
चरण 1 एपीआई आकार को समझें
प्रत्येक 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
आप अपने एपीआई कुंजी को हार्ड-कोडिंग के बजाय पर्यावरण चर में स्टोर कर सकते हैं. आप इसे वर्तमान खोल सत्र के लिए निर्यात कर सकते हैंः
export FXMD_API_KEY="your_actual_api_key_here"
सुरक्षा टिप
स्रोत फ़ाइलों में हार्ड-कोड एपीआई कुंजी कभी न करें या उन्हें संस्करण नियंत्रण के लिए प्रतिबद्ध करें। उत्पादन में एक रहस्य प्रबंधक या एक सीआई / सीडी पर्यावरण चर का उपयोग करें। यहां दिखाया गया पैटर्न स्टार्टअप पर कुंजी पढ़ता है और यदि चर गायब है तो तेजी से विफल रहता है।
चरण 3 प्रतिक्रिया के प्रकारों को परिभाषित करें
नामक एक फ़ाइल बनाएँ fxmd.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 कॉल कोड से बाहर बॉयलरप्लेट रखता है. क्लाइंट निर्माण में एक बार एपीआई कुंजी पढ़ता है, प्रत्येक अनुरोध पर एक क्वेरी पैरामीटर के रूप में इसे इंजेक्ट करता है, और एक समय सीमा लागू करता है ताकि धीमी अपस्ट्रीम कभी भी आपके प्रोग्राम को अनिश्चित काल तक रोक न सके:
// 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 उत्तर शरीर पर (बजाए इसके कि पहले शरीर को बाइट स्लाइस में पढ़ें) गो में मुहावरा दृष्टिकोण हैः यह 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
टिप गोरोटीन के साथ समवर्ती फ़ॉर्च
क्योंकि क्लाइंट एक साथ उपयोग के लिए सुरक्षित है, आप goroutines और का उपयोग कर समानांतर में कई संकेतक अनुरोध फैन कर सकते हैं sync.WaitGroup या errgroupयह विशेष रूप से उपयोगी है जब एक डैशबोर्ड का निर्माण एक बार में कई मुद्राओं को खींचता है दीवार घड़ी का समय सभी अनुरोधों के योग के बजाय सबसे धीमी एकल अनुरोध के विलंबता के करीब रहता है।
चरण 7 पृष्ठकरण और दिनांक सीमाओं को संभालें
डिफ़ॉल्ट रूप से घोषणाएं अंत बिंदु उपलब्ध इतिहास वापस करता है.
एम2 मुद्रा आपूर्ति या जीडीपी आप अक्सर विंडो का उपयोग करके सीमित करना चाहेंगे start और end query parameters दोनों सहायक पहले से ही उनका समर्थन करते हैं। यहाँ एक केंद्रित उदाहरण है जो केवल सबसे हालिया तिमाही को प्राप्त करता है
संयुक्त राज्य अमेरिका में अंशकालिक रोजगार डेटाः
// 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), जो एपीआई द्वारा अपेक्षित आईएसओ-8601 दिनांक स्ट्रिंग से मेल खाता है।
चरण 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)
}
}
}
आगे क्या है?
अब आपके पास एक कामकाजी गो क्लाइंट है जो तीन सबसे आम FXMacroData एंडपॉइंट परिवारों को कवर करता है। कुछ प्राकृतिक अगले कदमः
- संरचना की परिभाषाओं का विस्तार अतिरिक्त क्षेत्रों को कैप्चर करने के लिए जैसे कि
revisedकैलेंडर अंत बिंदु से मान। - जोड़ें
errgroup-आधारित फैन-आउट एक साथ कई मुद्राओं कोClientगोरोटीन के बीच साझा करने के लिए सुरक्षित है क्योंकिhttp.Clientडिजाइन से समवर्ती-सुरक्षित है। - स्थानीय SQLite डेटाबेस में परिणामों को बनाए रखें प्रयोग करना
database/sqlहल्के बैकटेस्टिंग या सिग्नल अनुसंधान के लिए। - पूर्ण सूचक सूची देखें डॉलर के लिए /api-data-docs/usd/मजदूरी और अन्य मुद्राओं के लिए डैशबोर्ड पर खोजें एम2, अंशकालिक रोजगार, और जीडीपी इस गाइड को प्रेरित करने वाले मांग संकेतों को देखते हुए, यह एक प्रारंभिक बिंदु है।