This guide provides detailed documentation of all data structures returned by yfinance-go, including field naming conventions, data types, and usage examples.
yfinance-go returns data in standardized, normalized formats that ensure consistency across different data sources. All monetary values use scaled decimal arithmetic for financial precision, and timestamps are in UTC.
All monetary values in yfinance-go use a scaled decimal format to ensure financial precision and avoid floating-point errors.
type ScaledDecimal struct {
Scaled int64 `json:"scaled"`
Scale int `json:"scale"`
}Purpose: Represents decimal numbers with explicit precision for financial calculations.
Conversion Formula: value = scaled / (10^scale)
Examples:
// Price: $255.03
{
"scaled": 25503,
"scale": 2
}
// Price: $1,234.5678
{
"scaled": 12345678,
"scale": 4
}
// Price: $100.00
{
"scaled": 10000,
"scale": 2
}Conversion Helper Function:
func formatScaledDecimal(scaled int64, scale int32) string {
if scale == 0 {
return fmt.Sprintf("%d", scaled)
}
divisor := 1.0
for i := int32(0); i < scale; i++ {
divisor *= 10.0
}
value := float64(scaled) / divisor
return fmt.Sprintf("%.2f", value)
}
// Usage
price := float64(quote.RegularMarketPrice.Scaled) /
float64(1<<uint(quote.RegularMarketPrice.Scale))
fmt.Printf("Price: $%.2f\n", price)Represents a financial security with identification information.
type Security struct {
Symbol string `json:"symbol"`
MIC string `json:"mic,omitempty"`
}Fields:
Symbol: Stock symbol (e.g., "AAPL", "MSFT")MIC: Market Identifier Code (e.g., "XNAS" for NASDAQ)
Contains metadata for tracking and lineage.
type Meta struct {
RunID string `json:"run_id"`
Source string `json:"source"`
Producer string `json:"producer"`
SchemaVersion string `json:"schema_version"`
IngestTime time.Time `json:"ingest_time"`
}Represents a single price bar (OHLCV data).
type NormalizedBar struct {
Start time.Time `json:"start"`
End time.Time `json:"end"`
Open ScaledDecimal `json:"open"`
High ScaledDecimal `json:"high"`
Low ScaledDecimal `json:"low"`
Close ScaledDecimal `json:"close"`
Volume int64 `json:"volume"`
Adjusted bool `json:"adjusted"`
AdjustmentPolicyID string `json:"adjustment_policy_id"`
CurrencyCode string `json:"currency_code"`
EventTime time.Time `json:"event_time"`
IngestTime time.Time `json:"ingest_time"`
AsOf time.Time `json:"as_of"`
}Field Descriptions:
Start: Bar start time (inclusive)End: Bar end time (exclusive)Open/High/Low/Close: Price data as scaled decimalsVolume: Trading volume as integerAdjusted: Whether prices are adjusted for splits/dividendsAdjustmentPolicyID: "raw", "split_only", or "split_dividend"CurrencyCode: ISO-4217 currency code (e.g., "USD", "EUR")EventTime: When the bar was recordedIngestTime: When data was ingestedAsOf: Data as-of timestamp
Usage Example:
for _, bar := range bars.Bars {
// Convert scaled decimal to float
open := float64(bar.Open.Scaled) / float64(bar.Open.Scale)
high := float64(bar.High.Scaled) / float64(bar.High.Scale)
low := float64(bar.Low.Scaled) / float64(bar.Low.Scale)
close := float64(bar.Close.Scaled) / float64(bar.Close.Scale)
fmt.Printf("Date: %s, OHLC: %.2f/%.2f/%.2f/%.2f, Volume: %d\n",
bar.EventTime.Format("2006-01-02"),
open, high, low, close, bar.Volume)
}Contains a collection of bars for a single security.
type NormalizedBarBatch struct {
Security Security `json:"security"`
Bars []NormalizedBar `json:"bars"`
Meta Meta `json:"meta"`
}Represents current market quote data.
type NormalizedQuote struct {
Security Security `json:"security"`
Type string `json:"type"`
Bid *ScaledDecimal `json:"bid,omitempty"`
BidSize *int64 `json:"bid_size,omitempty"`
Ask *ScaledDecimal `json:"ask,omitempty"`
AskSize *int64 `json:"ask_size,omitempty"`
RegularMarketPrice *ScaledDecimal `json:"regular_market_price,omitempty"`
RegularMarketHigh *ScaledDecimal `json:"regular_market_high,omitempty"`
RegularMarketLow *ScaledDecimal `json:"regular_market_low,omitempty"`
RegularMarketVolume *int64 `json:"regular_market_volume,omitempty"`
Venue string `json:"venue,omitempty"`
CurrencyCode string `json:"currency_code"`
EventTime time.Time `json:"event_time"`
IngestTime time.Time `json:"ingest_time"`
Meta Meta `json:"meta"`
}Field Naming Convention: Uses snake_case (regular_market_price, regular_market_volume)
Usage Example:
quote, err := client.FetchQuote(ctx, "AAPL", runID)
if err != nil {
log.Fatal(err)
}
fmt.Printf("Symbol: %s\n", quote.Security.Symbol)
if quote.RegularMarketPrice != nil {
price := float64(quote.RegularMarketPrice.Scaled) /
float64(quote.RegularMarketPrice.Scale)
fmt.Printf("Price: %.4f %s\n", price, quote.CurrencyCode)
}
if quote.RegularMarketVolume != nil {
fmt.Printf("Volume: %d\n", *quote.RegularMarketVolume)
}
fmt.Printf("Event Time: %s\n", quote.EventTime.Format("2006-01-02 15:04:05"))Comprehensive market data including 52-week ranges.
type NormalizedMarketData struct {
Security Security `json:"security"`
RegularMarketPrice *ScaledDecimal `json:"regular_market_price,omitempty"`
RegularMarketHigh *ScaledDecimal `json:"regular_market_high,omitempty"`
RegularMarketLow *ScaledDecimal `json:"regular_market_low,omitempty"`
RegularMarketVolume *int64 `json:"regular_market_volume,omitempty"`
FiftyTwoWeekHigh *ScaledDecimal `json:"fifty_two_week_high,omitempty"`
FiftyTwoWeekLow *ScaledDecimal `json:"fifty_two_week_low,omitempty"`
PreviousClose *ScaledDecimal `json:"previous_close,omitempty"`
ChartPreviousClose *ScaledDecimal `json:"chart_previous_close,omitempty"`
RegularMarketTime *time.Time `json:"regular_market_time,omitempty"`
HasPrePostMarketData bool `json:"has_pre_post_market_data"`
CurrencyCode string `json:"currency_code"`
EventTime time.Time `json:"event_time"`
IngestTime time.Time `json:"ingest_time"`
Meta Meta `json:"meta"`
}Basic company information from chart metadata.
type NormalizedCompanyInfo struct {
Security Security
LongName string `json:"long_name"`
ShortName string `json:"short_name"`
Exchange string `json:"exchange"`
FullExchangeName string `json:"full_exchange_name"`
Currency string `json:"currency"`
InstrumentType string `json:"instrument_type"`
FirstTradeDate *time.Time `json:"first_trade_date,omitempty"`
Timezone string `json:"timezone"`
ExchangeTimezone string `json:"exchange_timezone"`
EventTime time.Time `json:"event_time"`
IngestTime time.Time `json:"ingest_time"`
Meta Meta `json:"meta"`
}- Only returns basic security information
- Does NOT include: Company address, executives, website, employees, business summary
- Use case: Basic identification and exchange information only
Usage Example:
companyInfo, err := client.FetchCompanyInfo(ctx, "AAPL", runID)
if err != nil {
log.Fatal(err)
}
fmt.Printf("Company: %s\n", companyInfo.LongName)
fmt.Printf("Exchange: %s\n", companyInfo.Exchange)
fmt.Printf("Full Exchange: %s\n", companyInfo.FullExchangeName)
fmt.Printf("Currency: %s\n", companyInfo.Currency)
fmt.Printf("Instrument Type: %s\n", companyInfo.InstrumentType)
fmt.Printf("Timezone: %s\n", companyInfo.Timezone)Single line item in financial statements.
type NormalizedFundamentalsLine struct {
Key string `json:"key"`
Value ScaledDecimal `json:"value"`
CurrencyCode string `json:"currency_code"`
PeriodStart time.Time `json:"period_start"`
PeriodEnd time.Time `json:"period_end"`
}Common Keys:
eps_basic: Basic earnings per shareeps_diluted: Diluted earnings per sharerevenue: Total revenueebitda: Earnings before interest, taxes, depreciation, and amortizationnet_income: Net incometotal_assets: Total assetstotal_liabilities: Total liabilitiesmarket_cap: Market capitalizationpe_ratio: Price-to-earnings ratio
Collection of financial line items.
type NormalizedFundamentalsSnapshot struct {
Security Security `json:"security"`
Lines []NormalizedFundamentalsLine `json:"lines"`
Source string `json:"source"`
AsOf time.Time `json:"as_of"`
Meta Meta `json:"meta"`
}Usage Example:
financials, err := client.ScrapeFinancials(ctx, "AAPL", runID)
if err != nil {
log.Fatal(err)
}
fmt.Printf("Found %d financial line items:\n", len(financials.Lines))
for _, line := range financials.Lines {
value := float64(line.Value.Scaled) / float64(line.Value.Scale)
fmt.Printf("%s: %.2f %s\n", line.Key, value, line.CurrencyCode)
}The scraping methods return structured ampy-proto data that follows the same patterns but with additional metadata and validation.
type FundamentalsSnapshot struct {
Meta *Meta `protobuf:"bytes,1,opt,name=meta,proto3"`
Lines []*FundamentalsLine `protobuf:"bytes,2,rep,name=lines,proto3"`
// ... additional fields
}type NewsItem struct {
Title string `json:"title"`
Summary string `json:"summary"`
Url string `json:"url"`
PublishedAt time.Time `json:"published_at"`
Source string `json:"source"`
// ... additional fields
}All data structures follow consistent naming conventions:
-
Snake Case: All field names use snake_case
regular_market_priceregular_market_volumefifty_two_week_high
-
Pointer Fields: Optional fields are pointers (
*ScaledDecimal,*int64)- Allows distinction between zero values and missing data
-
Time Fields: All timestamps are
time.Timein UTCevent_time: When the data event occurredingest_time: When data was ingestedas_of: Data as-of timestamp
-
Currency Fields: All monetary fields include currency code
currency_code: ISO-4217 code (e.g., "USD", "EUR")
func validateBarData(bar *NormalizedBar) error {
if bar.Open.Scale < 0 || bar.High.Scale < 0 ||
bar.Low.Scale < 0 || bar.Close.Scale < 0 {
return fmt.Errorf("invalid scale values")
}
if bar.Volume < 0 {
return fmt.Errorf("negative volume")
}
if bar.Start.After(bar.End) {
return fmt.Errorf("start time after end time")
}
return nil
}
func validateQuoteData(quote *NormalizedQuote) error {
if quote.RegularMarketPrice != nil {
if quote.RegularMarketPrice.Scale < 0 {
return fmt.Errorf("invalid price scale")
}
}
if quote.CurrencyCode == "" {
return fmt.Errorf("missing currency code")
}
return nil
}| Expected Field | Actual Field | Data Type | Notes |
|---|---|---|---|
name |
long_name |
string | Company name |
price |
regular_market_price.scaled |
scaled decimal | Current price |
volume |
regular_market_volume |
number | Trading volume |
high |
regular_market_high.scaled |
scaled decimal | Daily high |
low |
regular_market_low.scaled |
scaled decimal | Daily low |
52_week_high |
fifty_two_week_high.scaled |
scaled decimal | 52-week high |
52_week_low |
fifty_two_week_low.scaled |
scaled decimal | 52-week low |
address |
Not available | N/A | Use alternative sources |
executives |
Not available | N/A | Use alternative sources |
website |
Not available | N/A | Use alternative sources |
employees |
Not available | N/A | Use alternative sources |
business_summary |
Not available | N/A | Use alternative sources |
if quote.RegularMarketPrice != nil {
price := float64(quote.RegularMarketPrice.Scaled) /
float64(quote.RegularMarketPrice.Scale)
fmt.Printf("Price: %.2f\n", price)
}// ✅ CORRECT: Use the scale field
price := float64(bar.Close.Scaled) / float64(bar.Close.Scale)
// ❌ WRONG: Don't hardcode division
// price := bar.Close.Scaled / 10000 // This is incorrect!func processFinancials(financials *NormalizedFundamentalsSnapshot) {
if len(financials.Lines) == 0 {
log.Printf("Warning: No financial data available")
return
}
for _, line := range financials.Lines {
if line.Value.Scale == 0 && line.Value.Scaled == 0 {
log.Printf("Warning: Zero value for %s", line.Key)
continue
}
// Process the line item
value := float64(line.Value.Scaled) / float64(line.Value.Scale)
fmt.Printf("%s: %.2f %s\n", line.Key, value, line.CurrencyCode)
}
}func validateDataQuality(data interface{}) error {
switch v := data.(type) {
case *NormalizedBarBatch:
if len(v.Bars) == 0 {
return fmt.Errorf("no bars in batch")
}
case *NormalizedQuote:
if v.RegularMarketPrice == nil {
return fmt.Errorf("missing market price")
}
case *NormalizedFundamentalsSnapshot:
if len(v.Lines) == 0 {
return fmt.Errorf("no financial lines")
}
}
return nil
}- Complete Examples - Working code examples with data processing
- Error Handling Guide - Comprehensive error handling
- API Reference - Complete API documentation