Skip to content
Merged
6 changes: 3 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@
- `QuoteContext.SymbolToCounterIds` — batch convert symbols to counter IDs via `POST /v1/quote/symbol-to-counter-ids`
- `QuoteContext.ResolveCounterIds` — local-first counter ID resolution with batched remote fallback and automatic caching
- `FundamentalContext.EtfAssetAllocation` — ETF asset allocation (holdings / regional / asset class / industry) via `GET /v1/quote/etf-asset-allocation`
- `FundamentalContext.MacrodataIndicators` — list macroeconomic indicators via `GET /v1/quote/macrodata`
- `FundamentalContext.Macrodata` — historical data for a specific indicator via `GET /v1/quote/macrodata/{indicator_code}`; `startDate` / `endDate` accept `"YYYY-MM-DD"` strings
- New types: `MultiLanguageText`, `MacrodataIndicator`, `Macrodata`, `MacrodataResponse`
- `FundamentalContext.MacroeconomicIndicators(country, offset, limit)` — list macroeconomic indicators via `GET /v1/quote/macrodata`; filter by `MacroeconomicCountry` (HK/CN/US/EU/JP/SG); response includes `Count`
- `FundamentalContext.Macroeconomic(indicatorCode, startDate, endDate, offset, limit)` — historical data for a specific indicator via `GET /v1/quote/macrodata/{indicator_code}`; `startDate` / `endDate` accept `"YYYY-MM-DD"` strings; response includes `Count`
- New types: `MultiLanguageText`, `MacroeconomicCountry`, `MacroeconomicImportance`, `MacroeconomicIndicator`, `MacroeconomicIndicatorListResponse`, `Macroeconomic`, `MacroeconomicResponse`

## [v0.24.2] - 2026-06-02

Expand Down
81 changes: 51 additions & 30 deletions fundamental/context.go
Original file line number Diff line number Diff line change
Expand Up @@ -1612,79 +1612,81 @@ func convertFinancialReportSnapshot(j *jsontypes.FinancialReportSnapshot) *Finan
}
}

// ─── Macrodata ────────────────────────────────────────────────────
// ─── Macroeconomic ────────────────────────────────────────────────────

// MacrodataIndicators fetches the list of available macroeconomic indicators.
// MacroeconomicIndicators fetches the list of available macroeconomic indicators.
//
// Pass offset and limit as nil to use the API defaults (offset=0, limit=100).
// To fetch all ~619 indicators in one call pass limit=1000.
// Pass country to filter by country code (e.g. MacroeconomicCountryUS).
// Pass nil for all countries.
//
// Path: GET /v1/quote/macrodata
func (c *FundamentalContext) MacrodataIndicators(
func (c *FundamentalContext) MacroeconomicIndicators(
ctx context.Context,
country *MacroeconomicCountry,
offset *int32,
limit *int32,
) ([]MacrodataIndicator, error) {
) (*MacroeconomicIndicatorListResponse, error) {
q := url.Values{}
if country != nil {
q.Set("country", macroeconomicCountryToAPIValue(*country))
}
if offset != nil {
q.Set("offset", fmt.Sprintf("%d", *offset))
}
if limit != nil {
q.Set("limit", fmt.Sprintf("%d", *limit))
}
var resp jsontypes.MacrodataIndicatorListResponse
var resp jsontypes.MacroeconomicIndicatorListResponse
if err := c.httpClient.Get(ctx, "/v1/quote/macrodata", q, &resp); err != nil {
return nil, err
}
out := make([]MacrodataIndicator, 0, len(resp.Data))
out := make([]MacroeconomicIndicator, 0, len(resp.Data))
for _, item := range resp.Data {
out = append(out, convertMacrodataIndicator(&item))
out = append(out, convertMacroeconomicIndicator(&item))
}
return out, nil
return &MacroeconomicIndicatorListResponse{Data: out, Count: resp.Count}, nil
}

// Macrodata fetches historical data for a specific macroeconomic
// indicator.
//
// startTime and endTime are Unix timestamps in seconds; pass nil to omit.
// limit defaults to 100 (max 100) when nil.
//
// Path: GET /v1/quote/macrodata/{indicator_code}
// Macrodata fetches historical data for a specific macroeconomic indicator.
// Macroeconomic fetches historical data for a specific macroeconomic indicator.
//
// startDate and endDate are date strings in "YYYY-MM-DD" format.
// startDate is sent as YYYY-MM-DDT00:00:00Z; endDate is sent as YYYY-MM-DDT23:59:59Z.
//
// Path: GET /v1/quote/macrodata/{indicator_code}
func (c *FundamentalContext) Macrodata(
func (c *FundamentalContext) Macroeconomic(
ctx context.Context,
indicatorCode string,
startDate *string,
endDate *string,
offset *int32,
limit *int32,
) (*MacrodataResponse, error) {
) (*MacroeconomicResponse, error) {
q := url.Values{}
if startDate != nil {
q.Set("start_time", *startDate+"T00:00:00Z")
}
if endDate != nil {
q.Set("end_time", *endDate+"T23:59:59Z")
}
if offset != nil {
q.Set("offset", fmt.Sprintf("%d", *offset))
}
if limit != nil {
q.Set("limit", fmt.Sprintf("%d", *limit))
}
var resp jsontypes.MacrodataResponse
var resp jsontypes.MacroeconomicResponse
path := "/v1/quote/macrodata/" + indicatorCode
if err := c.httpClient.Get(ctx, path, q, &resp); err != nil {
return nil, err
}
data := make([]Macrodata, 0, len(resp.Data))
data := make([]Macroeconomic, 0, len(resp.Data))
for _, d := range resp.Data {
data = append(data, convertMacrodata(&d))
data = append(data, convertMacroeconomic(&d))
}
return &MacrodataResponse{
Info: convertMacrodataIndicator(&resp.Info),
Data: data,
return &MacroeconomicResponse{
Info: convertMacroeconomicIndicator(&resp.Info),
Data: data,
Count: resp.Count,
}, nil
}

Expand All @@ -1708,8 +1710,8 @@ func parseOptionalRFC3339(s string) *time.Time {
return &t
}

func convertMacrodataIndicator(j *jsontypes.MacrodataIndicator) MacrodataIndicator {
return MacrodataIndicator{
func convertMacroeconomicIndicator(j *jsontypes.MacroeconomicIndicator) MacroeconomicIndicator {
return MacroeconomicIndicator{
IndicatorCode: j.IndicatorCode,
SourceOrg: j.SourceOrg,
Country: j.Country,
Expand All @@ -1723,8 +1725,8 @@ func convertMacrodataIndicator(j *jsontypes.MacrodataIndicator) MacrodataIndicat
}
}

func convertMacrodata(j *jsontypes.Macrodata) Macrodata {
return Macrodata{
func convertMacroeconomic(j *jsontypes.Macroeconomic) Macroeconomic {
return Macroeconomic{
Period: j.Period,
ReleaseAt: parseOptionalRFC3339(j.ReleaseAt),
ActualValue: j.ActualValue,
Expand All @@ -1736,3 +1738,22 @@ func convertMacrodata(j *jsontypes.Macrodata) Macrodata {
UnitPrefix: convertMultiLanguageText(j.UnitPrefix),
}
}

func macroeconomicCountryToAPIValue(c MacroeconomicCountry) string {
switch c {
case MacroeconomicCountryHK:
return "Hong Kong SAR China"
case MacroeconomicCountryCN:
return "China (Mainland)"
case MacroeconomicCountryUS:
return "United States"
case MacroeconomicCountryEU:
return "Euro Zone"
case MacroeconomicCountryJP:
return "Japan"
case MacroeconomicCountrySG:
return "Singapore"
default:
return string(c)
}
}
24 changes: 13 additions & 11 deletions fundamental/jsontypes/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -806,8 +806,8 @@ type MultiLanguageText struct {
TraditionalChinese string `json:"traditional_chinese"`
}

// MacrodataIndicator is the metadata for one macroeconomic indicator.
type MacrodataIndicator struct {
// MacroeconomicIndicator is the metadata for one macroeconomic indicator.
type MacroeconomicIndicator struct {
IndicatorCode string `json:"indicator_code"`
SourceOrg string `json:"source_org"`
Country string `json:"country"`
Expand All @@ -820,14 +820,15 @@ type MacrodataIndicator struct {
StartDate string `json:"start_date"`
}

// MacrodataIndicatorListResponse is the raw response for GET /v1/quote/macrodata.
type MacrodataIndicatorListResponse struct {
Data []MacrodataIndicator `json:"list"`
// MacroeconomicIndicatorListResponse is the raw response for GET /v1/quote/macrodata.
type MacroeconomicIndicatorListResponse struct {
Data []MacroeconomicIndicator `json:"list"`
Count int32 `json:"count"`
}

// Macrodata is one historical data point for a macroeconomic
// Macroeconomic is one historical data point for a macroeconomic
// indicator.
type Macrodata struct {
type Macroeconomic struct {
Period string `json:"period"`
ReleaseAt string `json:"release_at"`
ActualValue string `json:"actual_value"`
Expand All @@ -839,9 +840,10 @@ type Macrodata struct {
UnitPrefix MultiLanguageText `json:"unit_prefix"`
}

// MacrodataResponse is the raw response for
// MacroeconomicResponse is the raw response for
// GET /v1/quote/macrodata/{indicator_code}.
type MacrodataResponse struct {
Info MacrodataIndicator `json:"info"`
Data []Macrodata `json:"data"`
type MacroeconomicResponse struct {
Info MacroeconomicIndicator `json:"info"`
Data []Macroeconomic `json:"data"`
Count int32 `json:"count"`
}
52 changes: 41 additions & 11 deletions fundamental/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -1363,9 +1363,38 @@ type MultiLanguageText struct {
TraditionalChinese string
}

// MacrodataIndicator is the metadata for one macroeconomic indicator.
type MacrodataIndicator struct {
// IndicatorCode is the external vendor code (input to EconomicIndicator).
// MacroeconomicCountry is a country code for filtering macroeconomic indicators.
type MacroeconomicCountry string

const (
MacroeconomicCountryHK MacroeconomicCountry = "HK" // Hong Kong SAR China
MacroeconomicCountryCN MacroeconomicCountry = "CN" // China (Mainland)
MacroeconomicCountryUS MacroeconomicCountry = "US" // United States
MacroeconomicCountryEU MacroeconomicCountry = "EU" // Euro Zone
MacroeconomicCountryJP MacroeconomicCountry = "JP" // Japan
MacroeconomicCountrySG MacroeconomicCountry = "SG" // Singapore
)

// MacroeconomicImportance is the importance level of a macroeconomic indicator.
type MacroeconomicImportance int32

const (
MacroeconomicImportanceLow MacroeconomicImportance = 1
MacroeconomicImportanceMedium MacroeconomicImportance = 2
MacroeconomicImportanceHigh MacroeconomicImportance = 3
)

// MacroeconomicIndicatorListResponse is the response for FundamentalContext.MacroeconomicIndicators.
type MacroeconomicIndicatorListResponse struct {
// Data is the list of indicators.
Data []MacroeconomicIndicator
// Count is the total number of indicators matching the query.
Count int32
}

// MacroeconomicIndicator is the metadata for one macroeconomic indicator.
type MacroeconomicIndicator struct {
// IndicatorCode is the external vendor code (input to Macroeconomic).
IndicatorCode string
SourceOrg string
Country string
Expand All @@ -1375,15 +1404,14 @@ type MacrodataIndicator struct {
Periodicity string
Category string
Describe MultiLanguageText
// Importance — higher is more important.
// Importance: 1=Low, 2=Medium, 3=High.
Importance int32
// StartDate is the start date of data coverage; nil if unset.
StartDate *time.Time
}

// Macrodata is one historical data point for a macroeconomic
// indicator.
type Macrodata struct {
// Macroeconomic is one historical data point for a macroeconomic indicator.
type Macroeconomic struct {
// Period is the statistical period (e.g. "2024-Q1", "2024-03").
Period string
ReleaseAt *time.Time
Expand All @@ -1396,8 +1424,10 @@ type Macrodata struct {
UnitPrefix MultiLanguageText
}

// MacrodataResponse is the response for FundamentalContext.EconomicIndicator.
type MacrodataResponse struct {
Info MacrodataIndicator
Data []Macrodata
// MacroeconomicResponse is the response for FundamentalContext.Macroeconomic.
type MacroeconomicResponse struct {
Info MacroeconomicIndicator
Data []Macroeconomic
// Count is the total number of historical data points.
Count int32
}