diff --git a/.golangci.yml b/.golangci.yml index b696e16..0b4740c 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -19,6 +19,4 @@ linters: - exhaustivestruct - gci - gofumpt - - nonamedreturns - - exhaustruct diff --git a/cli.go b/cli.go index 4f0dcf6..95e30cc 100644 --- a/cli.go +++ b/cli.go @@ -91,15 +91,13 @@ func (c *Cli) GetTimeSeries( return nil, 0, 0, err } - errResp, err := c.CheckErrorInResponse(resp) - if err != nil { + // nolint: nestif + if errResp, err := c.CheckErrorInResponse(resp); err != nil { if errResp != nil && errResp.Code == http.StatusBadRequest { if strings.Contains(errResp.Message, dictionary.SymbolNotFoundMsg) || strings.Contains(errResp.Message, dictionary.NewSymbolNotFoundMsg) { return nil, creditsLeft, creditsUsed, dictionary.ErrNotFound - } - - if strings.Contains(errResp.Message, dictionary.IsNotAvailableWithYourPlanMsg) { + } else if strings.Contains(errResp.Message, dictionary.IsNotAvailableWithYourPlanMsg) { return nil, creditsLeft, creditsUsed, dictionary.ErrIsNotAvailableWithYourPlan } } @@ -111,10 +109,6 @@ func (c *Cli) GetTimeSeries( return nil, creditsLeft, creditsUsed, err } - if errResp.Code == http.StatusNotFound { - return nil, creditsLeft, creditsUsed, dictionary.ErrNotFound - } - if err := json.Unmarshal(resp.Body(), &seriesResp); err != nil { c.logger.Err(err).Bytes("body", resp.Body()).Msg("unmarshall") @@ -143,7 +137,7 @@ func (c *Cli) GetProfile(symbol, exchange, country string) ( return nil, 0, 0, err } - errResp, err := c.CheckErrorInResponse(resp) + _, err = c.CheckErrorInResponse(resp) if err != nil { if !errors.Is(err, dictionary.ErrTooManyRequests) { c.logger.Err(err).Msg("check error in response") @@ -152,10 +146,6 @@ func (c *Cli) GetProfile(symbol, exchange, country string) ( return nil, creditsLeft, creditsUsed, err } - if errResp.Code == http.StatusNotFound { - return nil, creditsLeft, creditsUsed, dictionary.ErrNotFound - } - if err := json.Unmarshal(resp.Body(), &profileResp); err != nil { c.logger.Err(err).Bytes("body", resp.Body()).Msg("unmarshall") @@ -184,7 +174,7 @@ func (c *Cli) GetInsiderTransactions(symbol, exchange, country string) ( return nil, 0, 0, err } - errResp, err := c.CheckErrorInResponse(resp) + _, err = c.CheckErrorInResponse(resp) if err != nil { if !errors.Is(err, dictionary.ErrTooManyRequests) { c.logger.Err(err).Msg("check error in response") @@ -193,10 +183,6 @@ func (c *Cli) GetInsiderTransactions(symbol, exchange, country string) ( return nil, creditsLeft, creditsUsed, err } - if errResp.Code == http.StatusNotFound { - return nil, creditsLeft, creditsUsed, dictionary.ErrNotFound - } - if err := json.Unmarshal(resp.Body(), &insiderTransactionsResp); err != nil { c.logger.Err(err).Bytes("body", resp.Body()).Msg("unmarshall") @@ -229,7 +215,7 @@ func (c *Cli) GetDividends(symbol, exchange, country, r, startDate, endDate stri return nil, 0, 0, err } - errResp, err := c.CheckErrorInResponse(resp) + _, err = c.CheckErrorInResponse(resp) if err != nil { if !errors.Is(err, dictionary.ErrTooManyRequests) { c.logger.Err(err).Msg("check error in response") @@ -238,10 +224,6 @@ func (c *Cli) GetDividends(symbol, exchange, country, r, startDate, endDate stri return nil, creditsLeft, creditsUsed, err } - if errResp.Code == http.StatusNotFound { - return nil, creditsLeft, creditsUsed, dictionary.ErrNotFound - } - if err := json.Unmarshal(resp.Body(), ÷ndsResp); err != nil { c.logger.Err(err).Bytes("body", resp.Body()).Msg("unmarshall") @@ -270,7 +252,7 @@ func (c *Cli) GetStatistics(symbol, exchange, country string) ( return nil, 0, 0, err } - errResp, err := c.CheckErrorInResponse(resp) + _, err = c.CheckErrorInResponse(resp) if err != nil { if !errors.Is(err, dictionary.ErrTooManyRequests) { c.logger.Err(err).Msg("check error in response") @@ -279,10 +261,6 @@ func (c *Cli) GetStatistics(symbol, exchange, country string) ( return nil, creditsLeft, creditsUsed, err } - if errResp.Code == http.StatusNotFound { - return nil, creditsLeft, creditsUsed, dictionary.ErrNotFound - } - if err := json.Unmarshal(resp.Body(), &statisticsResp); err != nil { c.logger.Err(err).Bytes("body", resp.Body()).Msg("unmarshall") @@ -449,7 +427,7 @@ func (c *Cli) GetUsage() ( return nil, 0, 0, err } - errResp, err := c.CheckErrorInResponse(resp) + _, err = c.CheckErrorInResponse(resp) if err != nil { if !errors.Is(err, dictionary.ErrTooManyRequests) { c.logger.Err(err).Msg("check error in response") @@ -458,10 +436,6 @@ func (c *Cli) GetUsage() ( return nil, creditsLeft, creditsUsed, err } - if errResp.Code == http.StatusNotFound { - return nil, creditsLeft, creditsUsed, dictionary.ErrNotFound - } - if err := json.Unmarshal(resp.Body(), &usageResp); err != nil { c.logger.Err(err).Bytes("body", resp.Body()).Msg("unmarshall") @@ -544,10 +518,6 @@ func (c *Cli) GetExchangeRate( return nil, creditsLeft, creditsUsed, err } - if errResp.Code == http.StatusNotFound { - return nil, creditsLeft, creditsUsed, dictionary.ErrNotFound - } - if err := json.Unmarshal(resp.Body(), &exchangeRate); err != nil { c.logger.Err(err).Bytes("body", resp.Body()).Msg("unmarshall") @@ -579,7 +549,7 @@ func (c *Cli) GetIncomeStatement(symbol, exchange, country, period, startDate, e return nil, 0, 0, err } - errResp, err := c.CheckErrorInResponse(resp) + _, err = c.CheckErrorInResponse(resp) if err != nil { if !errors.Is(err, dictionary.ErrTooManyRequests) { c.logger.Err(err).Msg("check error in response") @@ -588,10 +558,6 @@ func (c *Cli) GetIncomeStatement(symbol, exchange, country, period, startDate, e return nil, creditsLeft, creditsUsed, err } - if errResp.Code == http.StatusNotFound { - return nil, creditsLeft, creditsUsed, dictionary.ErrNotFound - } - if err := json.Unmarshal(resp.Body(), &incomeStatementResp); err != nil { c.logger.Err(err).Bytes("body", resp.Body()).Msg("unmarshall") @@ -623,7 +589,7 @@ func (c *Cli) GetBalanceSheet(symbol, exchange, country, startDate, endDate, per return nil, 0, 0, err } - errResp, err := c.CheckErrorInResponse(resp) + _, err = c.CheckErrorInResponse(resp) if err != nil { if !errors.Is(err, dictionary.ErrTooManyRequests) { c.logger.Err(err).Msg("check error in response") @@ -632,10 +598,6 @@ func (c *Cli) GetBalanceSheet(symbol, exchange, country, startDate, endDate, per return nil, creditsLeft, creditsUsed, err } - if errResp.Code == http.StatusNotFound { - return nil, creditsLeft, creditsUsed, dictionary.ErrNotFound - } - if err := json.Unmarshal(resp.Body(), &balanceSheetResp); err != nil { c.logger.Err(err).Bytes("body", resp.Body()).Msg("unmarshall") @@ -667,7 +629,7 @@ func (c *Cli) GetCashFlow(symbol, exchange, country, startDate, endDate, period return nil, 0, 0, err } - errResp, err := c.CheckErrorInResponse(resp) + _, err = c.CheckErrorInResponse(resp) if err != nil { if !errors.Is(err, dictionary.ErrTooManyRequests) { c.logger.Err(err).Msg("check error in response") @@ -676,10 +638,6 @@ func (c *Cli) GetCashFlow(symbol, exchange, country, startDate, endDate, period return nil, creditsLeft, creditsUsed, err } - if errResp.Code == http.StatusNotFound { - return nil, creditsLeft, creditsUsed, dictionary.ErrNotFound - } - if err := json.Unmarshal(resp.Body(), &cashFlowResp); err != nil { c.logger.Err(err).Bytes("body", resp.Body()).Msg("unmarshall") @@ -710,7 +668,7 @@ func (c *Cli) GetMarketMovers(instrument, direction string, outputSize int, coun return nil, 0, 0, err } - errResp, err := c.CheckErrorInResponse(resp) + _, err = c.CheckErrorInResponse(resp) if err != nil { if !errors.Is(err, dictionary.ErrTooManyRequests) { c.logger.Err(err).Msg("check error in response") @@ -719,10 +677,6 @@ func (c *Cli) GetMarketMovers(instrument, direction string, outputSize int, coun return nil, creditsLeft, creditsUsed, err } - if errResp.Code == http.StatusNotFound { - return nil, creditsLeft, creditsUsed, dictionary.ErrNotFound - } - if err := json.Unmarshal(resp.Body(), &marketMoversResp); err != nil { c.logger.Err(err).Bytes("body", resp.Body()).Msg("unmarshall") @@ -867,16 +821,15 @@ func (c *Cli) CheckErrorInResponse(resp *fasthttp.Response) (*response.Error, er return nil, dictionary.ErrUnmarshalResponse } - if errResp.Code == http.StatusBadRequest { + switch { + case errResp.Code == http.StatusBadRequest: return errResp, dictionary.ErrInvalidTwelveDataResponse - } - - if errResp.Code == http.StatusTooManyRequests { + case errResp.Code == http.StatusTooManyRequests: return nil, dictionary.ErrTooManyRequests - } - - if errResp.Code == http.StatusForbidden { + case errResp.Code == http.StatusForbidden: return errResp, dictionary.ErrForbidden + case errResp.Code == http.StatusNotFound: + return errResp, dictionary.ErrNotFound } return errResp, nil diff --git a/cli_test.go b/cli_test.go index ba6a659..cc4cce9 100644 --- a/cli_test.go +++ b/cli_test.go @@ -859,6 +859,7 @@ func TestCli_GetTimeSeries(t *testing.T) { "currency":"USD", "exchange_timezone":"America/New_York", "exchange":"NASDAQ", + "mic_code": "XNAS", "type":"Common Stock" }, "values":[ @@ -875,6 +876,7 @@ func TestCli_GetTimeSeries(t *testing.T) { Currency: "USD", ExchangeTimezone: "America/New_York", Exchange: "NASDAQ", + MicCode: "XNAS", Type: "Common Stock", }, Values: []*response.TimeSeriesValue{ @@ -1282,6 +1284,7 @@ func TestCli_GetQuotes(t *testing.T) { "symbol":"AAPL", "name":"Apple Inc", "exchange":"NASDAQ", + "mic_code": "XNAS", "currency":"USD", "datetime":"2022-02-08", "open":"171.73000", @@ -1308,6 +1311,7 @@ func TestCli_GetQuotes(t *testing.T) { Symbol: "AAPL", Name: "Apple Inc", Exchange: "NASDAQ", + MicCode: "XNAS", Currency: "USD", Datetime: "2022-02-08", Open: "171.73000", @@ -1543,6 +1547,7 @@ func TestCli_GetProfile(t *testing.T) { "symbol":"AAPL", "name":"Apple Inc", "exchange":"NASDAQ", + "mic_code": "XNAS", "sector":"Technology", "industry":"Consumer Electronics", "employees":154000, @@ -1561,6 +1566,7 @@ func TestCli_GetProfile(t *testing.T) { Symbol: "AAPL", Name: "Apple Inc", Exchange: "NASDAQ", + MicCode: "XNAS", Sector: "Technology", Industry: "Consumer Electronics", Employees: 154000, @@ -1726,6 +1732,7 @@ func TestCli_GetDividends(t *testing.T) { "name":"Apple Inc", "currency":"USD", "exchange":"NASDAQ", + "mic_code": "XNAS", "exchange_timezone":"America/New_York" }, "dividends":[ @@ -1738,6 +1745,7 @@ func TestCli_GetDividends(t *testing.T) { Name: "Apple Inc", Currency: "USD", Exchange: "NASDAQ", + MicCode: "XNAS", ExchangeTimezone: "America/New_York", }, Dividends: []*response.Dividend{ @@ -1897,96 +1905,57 @@ func TestCli_GetEarningsCalendar(t *testing.T) { responseCode: http.StatusOK, responseBody: ` { - "earnings": { - "2022-02-10": [ + "earnings":{ + "2020-05-08":[ { - "symbol": "02B", - "name": "BlackLine, Inc.", - "currency": "EUR", - "exchange": "FSX", - "time": "After Hours", - "eps_estimate": null, - "eps_actual": null, - "difference": null, - "surprise_prc": null - }, - { - "symbol": "096", - "name": "HubSpot Inc", - "currency": "EUR", - "exchange": "FSX", - "time": "After Hours", - "eps_estimate": null, - "eps_actual": null, - "difference": null, - "surprise_prc": null + "symbol": "BR", + "name": "Broadridge Financial Solutions Inc", + "currency": "USD", + "exchange": "NYSE", + "mic_code": "XNYS", + "country": "United States", + "time": "Time Not Supplied", + "eps_estimate": 1.72, + "eps_actual": 1.67, + "difference": -0.05, + "surprise_prc": -2.9 } ] }, - "status": "ok" - }`, + "status":"ok" + }`, wantResp: &response.Earnings{ Earnings: map[string][]*response.Earning{ - "2022-02-10": { - { - Symbol: "02B", - Name: "BlackLine, Inc.", - Currency: "EUR", - Exchange: "FSX", - Time: "After Hours", - EpsEstimate: null.Float{ - NullFloat64: sql.NullFloat64{ - Float64: 0, - Valid: false, - }, - }, - EpsActual: null.Float{ - NullFloat64: sql.NullFloat64{ - Float64: 0, - Valid: false, - }, - }, - Difference: null.Float{ - NullFloat64: sql.NullFloat64{ - Float64: 0, - Valid: false, - }, - }, - SurprisePrc: null.Float{ - NullFloat64: sql.NullFloat64{ - Float64: 0, - Valid: false, - }, - }, - }, + "2020-05-08": { { - Symbol: "096", - Name: "HubSpot Inc", - Currency: "EUR", - Exchange: "FSX", - Time: "After Hours", + Symbol: "BR", + Name: "Broadridge Financial Solutions Inc", + Currency: "USD", + Exchange: "NYSE", + MicCode: "XNYS", + Time: "Time Not Supplied", EpsEstimate: null.Float{ NullFloat64: sql.NullFloat64{ - Float64: 0, - Valid: false, + Float64: 1.72, + Valid: true, }, }, EpsActual: null.Float{ NullFloat64: sql.NullFloat64{ - Float64: 0, - Valid: false, + Float64: 1.67, + Valid: true, }, }, Difference: null.Float{ NullFloat64: sql.NullFloat64{ - Float64: 0, - Valid: false, + Float64: -0.05, + Valid: true, }, }, SurprisePrc: null.Float{ NullFloat64: sql.NullFloat64{ - Float64: 0, - Valid: false, + Float64: -2.9, + Valid: true, }, }, }, @@ -2116,6 +2085,7 @@ func TestCli_GetStatistics(t *testing.T) { "name": "Apple Inc", "currency": "USD", "exchange": "NASDAQ", + "mic_code": "XNAS", "exchange_timezone": "America/New_York" }, "statistics": { @@ -2200,6 +2170,7 @@ func TestCli_GetStatistics(t *testing.T) { Name: "Apple Inc", Currency: "USD", Exchange: "NASDAQ", + MicCode: "XNAS", ExchangeTimezone: "America/New_York", }, Statistics: &response.StatisticsValues{ @@ -2451,6 +2422,7 @@ func TestCli_GetBalanceSheet(t *testing.T) { "name": "Apple Inc", "currency": "USD", "exchange": "NASDAQ", + "mic_code": "XNAS", "exchange_timezone": "America/New_York", "period": "Annual" }, @@ -2522,6 +2494,7 @@ func TestCli_GetBalanceSheet(t *testing.T) { Name: "Apple Inc", Currency: "USD", Exchange: "NASDAQ", + MicCode: "XNAS", ExchangeTimezone: "America/New_York", Period: "Annual", }, @@ -2745,6 +2718,7 @@ func TestCli_GetCashFlow(t *testing.T) { "name": "Apple Inc", "currency": "USD", "exchange": "NASDAQ", + "mic_code": "XNAS", "exchange_timezone": "America/New_York", "period": "Annual" }, @@ -2794,6 +2768,7 @@ func TestCli_GetCashFlow(t *testing.T) { Name: "Apple Inc", Currency: "USD", Exchange: "NASDAQ", + MicCode: "XNAS", ExchangeTimezone: "America/New_York", Period: "Annual", }, @@ -2998,6 +2973,7 @@ func TestCli_GetIncomeStatement(t *testing.T) { "name": "Apple Inc", "currency": "USD", "exchange": "NASDAQ", + "mic_code": "XNAS", "exchange_timezone": "America/New_York", "period": "Annual" }, @@ -3035,6 +3011,7 @@ func TestCli_GetIncomeStatement(t *testing.T) { Name: "Apple Inc", Currency: "USD", Exchange: "NASDAQ", + MicCode: "XNAS", ExchangeTimezone: "America/New_York", Period: "Annual", }, @@ -3219,6 +3196,7 @@ func TestCli_GetInsiderTransactions(t *testing.T) { "name": "Apple Inc", "currency": "USD", "exchange": "NASDAQ", + "mic_code": "XNAS", "exchange_timezone": "America/New_York" }, "insider_transactions": [ @@ -3239,6 +3217,7 @@ func TestCli_GetInsiderTransactions(t *testing.T) { Name: "Apple Inc", Currency: "USD", Exchange: "NASDAQ", + MicCode: "XNAS", ExchangeTimezone: "America/New_York", }, InsiderTransactions: []*response.InsiderTransaction{ @@ -3503,6 +3482,7 @@ func TestCli_GetMarketMovers(t *testing.T) { "symbol": "FINKURVE", "name": "Finkurve Financial Services Limited", "exchange": "BSE", + "mic_code": "XNAS", "datetime": "2022-02-18 14:17:00", "last": 50.3, "high": 50.3, @@ -3519,6 +3499,7 @@ func TestCli_GetMarketMovers(t *testing.T) { Symbol: "FINKURVE", Name: "Finkurve Financial Services Limited", Exchange: "BSE", + MicCode: "XNAS", Datetime: "2022-02-18 14:17:00", Last: 50.3, High: 50.3, diff --git a/dictionary/errors.go b/dictionary/errors.go index eaffac0..43f5427 100644 --- a/dictionary/errors.go +++ b/dictionary/errors.go @@ -7,7 +7,7 @@ const NewSymbolNotFoundMsg = "**symbol** with specified criteria not found:" const IsNotAvailableWithYourPlanMsg = "is not available with your plan" var ( - ErrBadStatusCode = errors.New("bas status code") + ErrBadStatusCode = errors.New("bad status code") ErrInvalidTwelveDataResponse = errors.New("invalid twelvedata response") ErrTooManyRequests = errors.New("too many requests") ErrForbidden = errors.New("forbidden") diff --git a/response/balance_sheet.go b/response/balance_sheet.go index 9133d15..72836b3 100644 --- a/response/balance_sheet.go +++ b/response/balance_sheet.go @@ -10,6 +10,7 @@ type BalanceSheetsMeta struct { Name string `json:"name"` Currency string `json:"currency"` Exchange string `json:"exchange"` + MicCode string `json:"mic_code"` ExchangeTimezone string `json:"exchange_timezone"` Period string `json:"period"` } diff --git a/response/cash_flow.go b/response/cash_flow.go index 63d72d1..ab1e95f 100644 --- a/response/cash_flow.go +++ b/response/cash_flow.go @@ -10,6 +10,7 @@ type CashFlowsMeta struct { Name string `json:"name"` Currency string `json:"currency"` Exchange string `json:"exchange"` + MicCode string `json:"mic_code"` ExchangeTimezone string `json:"exchange_timezone"` Period string `json:"period"` } diff --git a/response/dividends.go b/response/dividends.go index ebff3e5..8c3f94a 100644 --- a/response/dividends.go +++ b/response/dividends.go @@ -10,6 +10,7 @@ type DividendsMeta struct { Name string `json:"name"` Currency string `json:"currency"` Exchange string `json:"exchange"` + MicCode string `json:"mic_code"` ExchangeTimezone string `json:"exchange_timezone"` } diff --git a/response/earning.go b/response/earning.go index 17dfbe2..69a4453 100644 --- a/response/earning.go +++ b/response/earning.go @@ -11,6 +11,7 @@ type Earning struct { Name string `json:"name"` Currency string `json:"currency"` Exchange string `json:"exchange"` + MicCode string `json:"mic_code"` Time string `json:"time"` EpsEstimate null.Float `json:"eps_estimate"` EpsActual null.Float `json:"eps_actual"` diff --git a/response/forex_time_series.go b/response/forex_time_series.go deleted file mode 100644 index 80c0f9f..0000000 --- a/response/forex_time_series.go +++ /dev/null @@ -1,19 +0,0 @@ -package response - -type ForexTimeSeries struct { - Meta struct { - Symbol string `json:"symbol"` - Interval string `json:"interval"` - CurrencyBase string `json:"currency_base"` - CurrencyQuote string `json:"currency_quote"` - Type string `json:"type"` - } `json:"meta"` - Values []struct { - Datetime string `json:"datetime"` - Open string `json:"open"` - High string `json:"high"` - Low string `json:"low"` - Close string `json:"close"` - } `json:"values"` - Status string `json:"status"` -} diff --git a/response/income_statement.go b/response/income_statement.go index 753e259..b52dca7 100644 --- a/response/income_statement.go +++ b/response/income_statement.go @@ -10,6 +10,7 @@ type IncomeStatementsMeta struct { Name string `json:"name"` Currency string `json:"currency"` Exchange string `json:"exchange"` + MicCode string `json:"mic_code"` ExchangeTimezone string `json:"exchange_timezone"` Period string `json:"period"` } diff --git a/response/insider_transactions.go b/response/insider_transactions.go index b0b72b1..4f8ce99 100644 --- a/response/insider_transactions.go +++ b/response/insider_transactions.go @@ -10,6 +10,7 @@ type InsiderTransactionsMeta struct { Name string `json:"name"` Currency string `json:"currency"` Exchange string `json:"exchange"` + MicCode string `json:"mic_code"` ExchangeTimezone string `json:"exchange_timezone"` } diff --git a/response/market_movers.go b/response/market_movers.go index 103e636..c7ad35e 100644 --- a/response/market_movers.go +++ b/response/market_movers.go @@ -9,6 +9,7 @@ type MarketMover struct { Symbol string `json:"symbol"` Name string `json:"name"` Exchange string `json:"exchange"` + MicCode string `json:"mic_code"` Datetime string `json:"datetime"` Last float64 `json:"last"` High float64 `json:"high"` diff --git a/response/profile.go b/response/profile.go index 6163f8e..c3a959d 100644 --- a/response/profile.go +++ b/response/profile.go @@ -4,6 +4,7 @@ type Profile struct { Symbol string `json:"symbol"` Name string `json:"name"` Exchange string `json:"exchange"` + MicCode string `json:"mic_code"` Sector string `json:"sector"` Industry string `json:"industry"` Employees int `json:"employees"` diff --git a/response/quote.go b/response/quote.go index f2cec64..b23df15 100644 --- a/response/quote.go +++ b/response/quote.go @@ -9,6 +9,7 @@ type Quote struct { Symbol string `json:"symbol"` Name string `json:"name"` Exchange string `json:"exchange"` + MicCode string `json:"mic_code"` Currency string `json:"currency"` Datetime string `json:"datetime"` Open string `json:"open"` diff --git a/response/statistics.go b/response/statistics.go index 56745fc..55c0076 100644 --- a/response/statistics.go +++ b/response/statistics.go @@ -10,6 +10,7 @@ type StatisticsMeta struct { Name string `json:"name"` Currency string `json:"currency"` Exchange string `json:"exchange"` + MicCode string `json:"mic_code"` ExchangeTimezone string `json:"exchange_timezone"` } diff --git a/response/time_series.go b/response/time_series.go index 7b96b58..0adbf68 100644 --- a/response/time_series.go +++ b/response/time_series.go @@ -12,6 +12,7 @@ type TimeSeriesMeta struct { Currency string `json:"currency"` ExchangeTimezone string `json:"exchange_timezone"` Exchange string `json:"exchange"` + MicCode string `json:"mic_code"` Type string `json:"type"` }