β οΈ IMPORTANT DISCLAIMERβ οΈ This project is NOT affiliated with, endorsed by, or sponsored by Yahoo Finance or Yahoo Inc.
This is an independent, open-source Go client that accesses publicly available financial data from Yahoo Finance's website. Yahoo Finance does not provide an official API for this data, and this client operates by scraping publicly accessible web pages.
Use at your own risk. Yahoo Finance may change their website structure at any time, which could break this client. We make no guarantees about data accuracy, availability, or compliance with Yahoo Finance's terms of service.
Legal Notice: Users are responsible for ensuring their use of this software complies with Yahoo Finance's terms of service and applicable laws in their jurisdiction.
The Challenge: Most financial data clients suffer from inconsistent data formats, unreliable APIs, and poor error handling. When building financial applications, developers often face:
- Inconsistent Data Formats: Different APIs return data in various shapes and formats
- Floating Point Precision Issues: Financial calculations require exact decimal precision
- Rate Limiting Problems: Unbounded requests lead to API bans and throttling
- Poor Error Handling: Limited retry logic and circuit breaking
- Currency Conversion Complexity: Multi-currency support is often missing or buggy
- No Standardization: Each client has its own data structures and conventions
Our Solution: A production-grade Go client that provides:
β
Standardized Data Formats - Consistent ampy-proto message structures
β
High Precision Decimals - Scaled decimal arithmetic for financial accuracy
β
Robust Rate Limiting - Built-in backoff, circuit breakers, and session rotation
β
Multi-Currency Support - Automatic currency conversion with FX providers
β
Production Ready - Comprehensive error handling, observability, and monitoring
β
Easy Integration - Simple API with both library and CLI interfaces
go get github.com/AmpyFin/yfinance-gogit clone https://github.com/AmpyFin/yfinance-go.git
cd yfinance-go
go build ./cmd/yfinpackage main
import (
"context"
"fmt"
"log"
"time"
"github.com/AmpyFin/yfinance-go"
)
func main() {
// Create a new client
client := yfinance.NewClient()
ctx := context.Background()
// Fetch daily bars for Apple
start := time.Date(2024, 1, 1, 0, 0, 0, 0, time.UTC)
end := time.Date(2024, 1, 31, 0, 0, 0, 0, time.UTC)
bars, err := client.FetchDailyBars(ctx, "AAPL", start, end, true, "my-run-id")
if err != nil {
log.Fatal(err)
}
fmt.Printf("Fetched %d bars for AAPL\n", len(bars.Bars))
for _, bar := range bars.Bars {
price := float64(bar.Close.Scaled) / float64(bar.Close.Scale)
fmt.Printf("Date: %s, Close: %.4f %s\n",
bar.EventTime.Format("2006-01-02"),
price, bar.CurrencyCode)
}
}// Default client with standard configuration
client := yfinance.NewClient()
// Client with session rotation (recommended for production)
client := yfinance.NewClientWithSessionRotation()FetchDailyBars - Get daily OHLCV data
bars, err := client.FetchDailyBars(ctx, "AAPL", start, end, adjusted, runID)FetchIntradayBars - Get intraday data (1m, 5m, 15m, 30m, 60m)
bars, err := client.FetchIntradayBars(ctx, "AAPL", start, end, "1m", runID)Note: Intraday data may not be available for all symbols and may return HTTP 422 errors for some requests.
FetchWeeklyBars - Get weekly OHLCV data
bars, err := client.FetchWeeklyBars(ctx, "AAPL", start, end, adjusted, runID)FetchMonthlyBars - Get monthly OHLCV data
bars, err := client.FetchMonthlyBars(ctx, "AAPL", start, end, adjusted, runID)FetchQuote - Get current market quote
quote, err := client.FetchQuote(ctx, "AAPL", runID)FetchMarketData - Get comprehensive market data
marketData, err := client.FetchMarketData(ctx, "AAPL", runID)FetchCompanyInfo - Get basic company information
companyInfo, err := client.FetchCompanyInfo(ctx, "AAPL", runID)FetchFundamentalsQuarterly - Get quarterly financials (requires paid subscription)
fundamentals, err := client.FetchFundamentalsQuarterly(ctx, "AAPL", runID)When Yahoo Finance API endpoints are unavailable, rate-limited, or require paid subscriptions, yfinance-go automatically falls back to web scraping with full data consistency guarantees.
- Automatic Fallback: Seamlessly switches between API and scraping
- Data Consistency: Identical output formats regardless of source
- Production Safety: Respects robots.txt, implements proper rate limiting
- Comprehensive Coverage: Access data not available through APIs
- Key Statistics: P/E ratios, market cap, financial metrics
- Financials: Income statements, balance sheets, cash flow
- Analysis: Comprehensive analyst data including:
- Earnings estimates (current/next quarter, current/next year)
- EPS trends (current estimate, 7/30/60/90 days ago)
- EPS revisions (up/down revisions in last 7/30 days)
- Revenue estimates (quarterly and annual)
- Growth estimates
- Analyst Insights: Target prices, recommendations, analyst counts
- Profile: Company information, executives, business summary
- News: Recent news articles and press releases
// Scrape key statistics (not available through free API)
keyStats, err := client.ScrapeKeyStatistics(ctx, "AAPL", runID)
// Scrape financial statements
financials, err := client.ScrapeFinancials(ctx, "AAPL", runID)
// Scrape comprehensive analysis data (earnings trends, EPS revisions, revenue estimates)
analysis, err := client.ScrapeAnalysis(ctx, "AAPL", runID)
// Scrape analyst insights (target prices, recommendations)
analystInsights, err := client.ScrapeAnalystInsights(ctx, "AAPL", runID)
// Scrape news articles
news, err := client.ScrapeNews(ctx, "AAPL", runID)# Scrape key statistics with preview
yfin scrape --ticker AAPL --endpoint key-statistics --preview
# Multiple endpoints with JSON output
yfin scrape --ticker AAPL --endpoints key-statistics,financials,news --preview-json
# Soak testing for production validation
yfin soak --universe-file universe.txt --duration 2h --qps 5 --previewπ Complete Scrape Documentation β
package main
import (
"context"
"fmt"
"log"
"sync"
"time"
"github.com/AmpyFin/yfinance-go"
)
func main() {
client := yfinance.NewClient()
ctx := context.Background()
symbols := []string{"AAPL", "GOOGL", "MSFT", "TSLA"}
start := time.Date(2024, 1, 1, 0, 0, 0, 0, time.UTC)
end := time.Date(2024, 1, 31, 0, 0, 0, 0, time.UTC)
var wg sync.WaitGroup
results := make(chan string, len(symbols))
for _, symbol := range symbols {
wg.Add(1)
go func(sym string) {
defer wg.Done()
bars, err := client.FetchDailyBars(ctx, sym, start, end, true, "batch-run")
if err != nil {
results <- fmt.Sprintf("Error fetching %s: %v", sym, err)
return
}
results <- fmt.Sprintf("%s: %d bars fetched", sym, len(bars.Bars))
}(symbol)
}
wg.Wait()
close(results)
for result := range results {
fmt.Println(result)
}
}package main
import (
"context"
"fmt"
"log"
"time"
"github.com/AmpyFin/yfinance-go"
)
func main() {
client := yfinance.NewClient()
ctx := context.Background()
quote, err := client.FetchQuote(ctx, "AAPL", "quote-run")
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"))
}package main
import (
"context"
"fmt"
"log"
"github.com/AmpyFin/yfinance-go"
)
func main() {
client := yfinance.NewClient()
ctx := context.Background()
companyInfo, err := client.FetchCompanyInfo(ctx, "AAPL", "company-run")
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)
}package main
import (
"context"
"fmt"
"log"
"time"
"github.com/AmpyFin/yfinance-go"
)
func main() {
client := yfinance.NewClient()
ctx := context.Background()
// Fetch data with proper error handling
bars, err := client.FetchDailyBars(ctx, "AAPL",
time.Date(2024, 1, 1, 0, 0, 0, 0, time.UTC),
time.Date(2024, 1, 31, 0, 0, 0, 0, time.UTC),
true, "error-handling-run")
if err != nil {
log.Printf("Error fetching bars: %v", err)
return
}
fmt.Printf("Successfully fetched %d bars\n", len(bars.Bars))
// Handle empty results
if len(bars.Bars) == 0 {
fmt.Println("No data available for the specified date range")
return
}
// Process the data
for _, bar := range bars.Bars {
price := float64(bar.Close.Scaled) / float64(bar.Close.Scale)
fmt.Printf("Date: %s, Close: %.4f %s\n",
bar.EventTime.Format("2006-01-02"),
price, bar.CurrencyCode)
}
}Note: For the latest release notes, see Release Notes. For the complete changelog, see CHANGELOG.md.
- Installation Guide - Setup and installation instructions
- Usage Guide - Comprehensive usage examples and patterns
- API Reference - Complete API documentation with method capabilities and limitations
- Data Structures - Detailed data structure guide with field naming conventions
- Complete Examples - Working code examples with data processing and error handling
- Method Comparison - Method comparison table and use case guidance
- Migration Guide - Migration from Python yfinance with feature comparison
- Error Handling Guide - Comprehensive error handling and troubleshooting
- Data Quality Guide - Data quality expectations and validation guidelines
- Performance Guide - Performance optimization and best practices
- Scrape Overview - Architecture and data flow
- Configuration Guide - All configuration options and best practices
- CLI Usage - Command-line interface examples
- Troubleshooting - Common issues and solutions
- Observability Guide - Metrics, logging, and monitoring
- Soak Testing Guide - Load testing and validation
- Production Readiness Report - Production readiness assessment and checklist
- Testing Implementation - Testing strategy and implementation details
- Release Guide - Release process and procedures
- Release Notes - Version release notes and changelog
- Audit Report - Comprehensive repository audit findings
- Audit Summary - Summary of audit results and fixes
- Final Audit Summary - Final audit validation
- Scrape Fallback Runbook - Operational procedures
- Incident Response Playbook - Emergency response procedures
- Library Examples - Go code examples and patterns
- CLI Examples - Ready-to-run shell scripts
- API Usage Example - Basic API usage
- Historical Data Example - Time series data
The yfin CLI tool provides command-line access to all functionality:
Note: All CLI commands require a configuration file. Use
--config configs/effective.yamlor set up your own config file.
# Build from source
go build -o yfin ./cmd/yfin
# Or install globally
go install github.com/AmpyFin/yfinance-go/cmd/yfin@latest# Fetch daily bars for a single symbol
yfin pull --ticker AAPL --start 2024-01-01 --end 2024-12-31 --adjusted split_dividend --preview --config configs/effective.yaml
# Fetch data for multiple symbols from a file
yfin pull --universe-file symbols.txt --start 2024-01-01 --end 2024-12-31 --publish --env prod --config configs/effective.yaml
# Get current quote
yfin quote --tickers AAPL --preview --config configs/effective.yaml
# Get fundamentals (requires paid subscription)
yfin fundamentals --ticker AAPL --preview --config configs/effective.yaml# Scrape key statistics (not available through free API)
yfin scrape --ticker AAPL --endpoint key-statistics --preview --config configs/effective.yaml
# Multiple endpoints with JSON preview
yfin scrape --ticker AAPL --endpoints key-statistics,financials,analysis --preview-json --config configs/effective.yaml
# News articles preview
yfin scrape --ticker AAPL --endpoint news --preview-news --config configs/effective.yaml
# Health check for endpoints
yfin scrape --ticker AAPL --endpoint key-statistics --check --config configs/effective.yaml# Quick smoke test (10 minutes)
yfin soak --universe-file testdata/universe/soak.txt --endpoints key-statistics,news --duration 10m --concurrency 8 --qps 5 --preview --config configs/effective.yaml
# Full production soak test (2 hours)
yfin soak --universe-file testdata/universe/soak.txt --endpoints key-statistics,financials,analysis,profile,news --duration 2h --concurrency 12 --qps 5 --preview --config configs/effective.yaml--ticker- Single symbol to fetch--universe-file- File containing list of symbols--start,--end- Date range (UTC)--adjusted- Adjustment policy (raw, split_only, split_dividend)--publish- Publish to ampy-bus--env- Environment (dev, staging, prod)--preview- Show data preview without publishing--concurrency- Number of concurrent requests--qps- Requests per second limit
--endpoint- Single endpoint to scrape--endpoints- Comma-separated list of endpoints--fallback- Fallback strategy (auto, api-only, scrape-only)--preview-json- JSON preview of multiple endpoints--preview-news- Preview news articles--preview-proto- Preview proto summaries--check- Validate endpoint accessibility--force- Override robots.txt (testing only)
--duration- Test duration (e.g., 2h, 30m)--memory-check- Enable memory leak detection--probe-interval- Correctness probe interval--failure-rate- Simulated failure rate for testing
π Complete CLI Documentation β
Mission
Provide a reliable, consistent, and fast Yahoo Finance client in Go that speaks Ampy's canonical contracts (ampy-proto) and optionally emits to ampy-bus, so ingestion pipelines and research tools work identically across providers.
Success looks like
- Library returns validated
ampy-protomessages with correct UTC times, currency semantics, and adjustment flags. - CLI supports on-demand pulls and batch backfills; ops can dryβrun, preview, and publish with a single command.
- Concurrency and backoff keep error rates and 429/503 responses within policy; throughput is tunable and predictable.
- Golden samples roundβtrip across Go β Python/C++ consumers without shape drift.
- Observability shows latency/throughput, decode failures, and backoff behavior; alerts catch regressions.
- Historical Bars - Daily, weekly, monthly, and intraday OHLCV data
- Real-time Quotes - Current market prices, bid/ask, volume
- Company Information - Basic company details, exchange info, industry/sector
- Market Data - 52-week ranges, market state, trading hours
- Multi-Currency Support - Automatic currency conversion with FX providers
These data types require paid Yahoo Finance subscriptions through the API, but are available through the scrape fallback system:
- Financial Statements - Income statement, balance sheet, cash flow β Available via scraping
- Analyst Recommendations - Price targets, ratings β Available via scraping
- Key Statistics - P/E ratios, market cap, financial metrics β Available via scraping
- Company Profiles - Business summary, executives, sector info β Available via scraping
- News Articles - Recent news and press releases β Available via scraping
- Options Data - Options chains and pricing
- Insider Trading - Insider transactions
- Institutional Holdings - Major shareholders
- Level 2 Market Data - Order book, bid/ask depth
- US Markets - NYSE, NASDAQ, AMEX
- International - Major exchanges worldwide
- Currencies - Forex pairs and cryptocurrency
- Commodities - Gold, oil, agricultural products
- Indices - S&P 500, Dow Jones, NASDAQ Composite
- Rate Limiting - Built-in QPS limits and burst control
- Circuit Breakers - Automatic failure detection and recovery
- Retry Logic - Exponential backoff with jitter
- Session Rotation - Prevents IP blocking and rate limits
- Scrape Fallback - Automatic APIβscrape fallback with robots.txt compliance
- Observability - Comprehensive metrics, logs, and tracing
- Soak Testing - Built-in load testing and robustness validation
- High Precision Decimals - Scaled decimal arithmetic for exact calculations
- Currency Support - Multi-currency with automatic conversion
- Corporate Actions - Split and dividend adjustments
- Market Hours - Proper handling of trading sessions and holidays
- Concurrent Requests - Configurable goroutine pools
- Connection Pooling - Efficient HTTP connection reuse
- Caching - Built-in response caching for FX rates
- Batching - Efficient data batching and chunking
- Simple API - Clean, intuitive Go interface
- Type Safety - Strongly typed data structures
- Error Handling - Comprehensive error types and messages
- CLI Tool - Command-line interface for operations
- Documentation - Extensive examples and API docs
- Time: All timestamps UTC ISOβ8601. Bars use
startinclusive,endexclusive;event_timeat bar close. - Precision: Prices/amounts are scaled decimals (
scaled,scale). Volumes are integers. - Currency: Attach ISOβ4217 code to monetary fields and fundamentals lines.
- Identity: Use
SecurityId={ symbol, mic?, figi?, isin? }. If MIC is unknown, prefer primary listing inference; document fallback rules. - Adjustments: Bars declare
adjusted: true|falseandadjustment_policy_id: "raw" | "split_only" | "split_dividend". - Lineage: Every message has
meta.run_id,meta.source="yfinance-go",meta.producer="<host|pod>",schema_version. - Batching: Prefer
BarBatchfor efficiency. Maintain inβbatch order byevent_timeascending. - Compatibility: Additive evolution only; breaking changes require new major (
bars.v2,fundamentals.v2).
All prices are stored as ScaledDecimal with explicit scale for financial precision:
// β
CORRECT: Use the scale field to convert back to decimal
price := float64(bar.Close.Scaled) / float64(bar.Close.Scale)
fmt.Printf("Price: %.4f %s\n", price, bar.CurrencyCode)
// β WRONG: Don't hardcode division by 10000
// price := bar.Close.Scaled / 10000 // This is incorrect!Example:
- Raw Yahoo price: $221.74
- Stored as:
Scaled: 22174, Scale: 2 - Converted back:
22174 / 100 = 221.74β
# Rate limiting
export YFIN_QPS=2.0
export YFIN_BURST=5
export YFIN_CONCURRENCY=32
# Timeouts
export YFIN_TIMEOUT=30s
export YFIN_BACKOFF_BASE=1s
export YFIN_BACKOFF_MAX=10s
# Circuit breaker
export YFIN_CIRCUIT_THRESHOLD=5
export YFIN_CIRCUIT_RESET=30s
# Observability
export YFIN_LOG_LEVEL=info
export YFIN_METRICS_ENABLED=true# config.yaml
yahoo:
timeout_ms: 30000
base_url: "https://query1.finance.yahoo.com"
concurrency:
global_workers: 32
max_inflight: 64
rate_limit:
per_host_qps: 2.0
burst: 5
retry:
attempts: 3
backoff_base_ms: 1000
backoff_max_ms: 10000
circuit_breaker:
failure_threshold: 5
reset_timeout_ms: 30000
observability:
log_level: "info"
metrics_enabled: true
tracing_enabled: false# Make scripts executable
chmod +x examples/cli/*.sh
# Run AAPL preview examples
./examples/cli/preview_aapl.sh
# Run soak testing examples
./examples/cli/soak_smoke.sh
# Run batch processing examples
./examples/cli/batch_processing.sh# Build and run library examples
go build -o examples/library/scrape_fallback examples/library/scrape_fallback.go
./examples/library/scrape_fallbackπ All Examples β
We welcome contributions! Please see our Contributing Guide for details.
# Clone the repository
git clone https://github.com/AmpyFin/yfinance-go.git
cd yfinance-go
# Install dependencies
go mod download
# Run tests
go test ./...
# Build CLI
go build -o yfin ./cmd/yfin
# Run integration tests
go test -tags=integration ./...- Follow Go standard formatting (
gofmt) - Use meaningful variable and function names
- Add tests for new functionality
- Update documentation for API changes
This project is licensed under the MIT License - see the LICENSE file for details.
- Yahoo Finance for providing publicly accessible financial data
- AmpyFin for the ampy-proto schemas and infrastructure
- Go Community for excellent libraries and tools
- Contributors who help improve this project
- Issues: GitHub Issues
- Discussions: GitHub Discussions
- Documentation: Complete Documentation
- API Reference: GoDoc
- Check Documentation: Start with docs/ for comprehensive guides
- Review Examples: See examples/ for code samples
- Search Issues: Check existing GitHub Issues
- Troubleshooting: See docs/scrape/troubleshooting.md
- Runbooks: For operational issues, see runbooks/
β If you find this project useful, please give it a star on GitHub!