Skip to content

client

import "github.com/wnjoon/go-yfinance/pkg/client"

Package client provides HTTP client functionality for accessing Yahoo Finance API.

Overview

The client package handles all HTTP communication with Yahoo Finance servers, including TLS fingerprint spoofing using CycleTLS to avoid detection and blocking.

Authentication

Yahoo Finance API requires cookie/crumb authentication. This is handled automatically by the AuthManager which supports two strategies:

  • Basic: Uses fc.yahoo.com for cookie acquisition (default)
  • CSRF: Uses guce.yahoo.com consent flow (for EU users)

The AuthManager automatically falls back to the alternate strategy if one fails.

Usage

c, err := client.New(
    client.WithTimeout(30),
    client.WithUserAgent("Custom UA"),
)
if err != nil {
    log.Fatal(err)
}
defer c.Close()

resp, err := c.Get("https://query2.finance.yahoo.com/v8/finance/chart/AAPL", nil)

Error Handling

The package provides typed errors via YFError for easy error handling:

if client.IsRateLimitError(err) {
    // Handle rate limiting
}

See ErrorCode for all available error types.

Index

Variables

Predefined errors for easy comparison

var (
    ErrNetwork         = &YFError{Code: ErrCodeNetwork, Message: "network error"}
    ErrAuth            = &YFError{Code: ErrCodeAuth, Message: "authentication error"}
    ErrRateLimit       = &YFError{Code: ErrCodeRateLimit, Message: "rate limited"}
    ErrNotFound        = &YFError{Code: ErrCodeNotFound, Message: "not found"}
    ErrInvalidSymbol   = &YFError{Code: ErrCodeInvalidSymbol, Message: "invalid symbol"}
    ErrInvalidResponse = &YFError{Code: ErrCodeInvalidResponse, Message: "invalid response"}
    ErrNoData          = &YFError{Code: ErrCodeNoData, Message: "no data available"}
    ErrTimeout         = &YFError{Code: ErrCodeTimeout, Message: "request timeout"}
)

UserAgents contains browser User-Agent strings for request rotation.

var UserAgents = []string{

    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/133.0.0.0 Safari/537.36",
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/133.0.0.0 Safari/537.36",
    "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/133.0.0.0 Safari/537.36",

    "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:135.0) Gecko/20100101 Firefox/135.0",
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 14.7; rv:135.0) Gecko/20100101 Firefox/135.0",
    "Mozilla/5.0 (X11; Linux i686; rv:135.0) Gecko/20100101 Firefox/135.0",

    "Mozilla/5.0 (Macintosh; Intel Mac OS X 14_7_4) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.3 Safari/605.1.15",

    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/133.0.0.0 Safari/537.36 Edg/131.0.2903.86",
}

func IsAuthError

func IsAuthError(err error) bool

IsAuthError checks if the error is an authentication error.

func IsInvalidSymbolError

func IsInvalidSymbolError(err error) bool

IsInvalidSymbolError checks if the error is an invalid symbol error.

func IsNoDataError

func IsNoDataError(err error) bool

IsNoDataError checks if the error is a no data error.

func IsNotFoundError

func IsNotFoundError(err error) bool

IsNotFoundError checks if the error is a not found error.

func IsRateLimitError

func IsRateLimitError(err error) bool

IsRateLimitError checks if the error is a rate limit error.

func IsTimeoutError

func IsTimeoutError(err error) bool

IsTimeoutError checks if the error is a timeout error.

func RandomUserAgent

func RandomUserAgent() string

RandomUserAgent returns a random User-Agent string.

type AuthManager

AuthManager handles Yahoo Finance authentication (Cookie + Crumb).

type AuthManager struct {
    // contains filtered or unexported fields
}

func NewAuthManager

func NewAuthManager(client *Client) *AuthManager

NewAuthManager creates a new AuthManager with the given client.

func (*AuthManager) AddCrumbToParams

func (a *AuthManager) AddCrumbToParams(params url.Values) (url.Values, error)

AddCrumbToParams adds the crumb parameter to URL values.

func (*AuthManager) CheckLogin

func (a *AuthManager) CheckLogin() (bool, error)

CheckLogin checks whether the current Yahoo cookies represent a logged-in user.

func (*AuthManager) GetCrumb

func (a *AuthManager) GetCrumb() (string, error)

GetCrumb returns the current crumb, fetching it if necessary.

func (*AuthManager) Reset

func (a *AuthManager) Reset()

Reset clears the authentication state.

func (*AuthManager) SetLoginCookies

func (a *AuthManager) SetLoginCookies(cookieT, cookieY string)

SetLoginCookies sets manually retrieved Yahoo Finance login cookies.

func (*AuthManager) SwitchStrategy

func (a *AuthManager) SwitchStrategy()

SwitchStrategy switches to the alternate authentication strategy.

func (*AuthManager) User

func (a *AuthManager) User() map[string]interface{}

User returns the cached logged-in Yahoo user payload, if available.

type AuthStrategy

AuthStrategy represents the authentication strategy.

type AuthStrategy int

const (
    // StrategyBasic uses fc.yahoo.com for cookie acquisition.
    StrategyBasic AuthStrategy = iota
    // StrategyCSRF uses guce.yahoo.com consent flow for cookie acquisition.
    StrategyCSRF
)

type Client

Client is the HTTP client for Yahoo Finance API with TLS fingerprint spoofing.

type Client struct {
    // contains filtered or unexported fields
}

func New

func New(opts ...ClientOption) (*Client, error)

New creates a new Client with optional configuration. The underlying CycleTLS client is lazily initialized on first request.

func (*Client) Close

func (c *Client) Close()

Close closes the CycleTLS client.

func (*Client) Get

func (c *Client) Get(rawURL string, params url.Values) (*Response, error)

Get performs an HTTP GET request.

func (*Client) GetCookie

func (c *Client) GetCookie() string

GetCookie returns the current cookie.

func (*Client) GetJSON

func (c *Client) GetJSON(rawURL string, params url.Values, v interface{}) error

GetJSON performs an HTTP GET request and unmarshals the JSON response.

func (*Client) Post

func (c *Client) Post(rawURL string, params url.Values, body map[string]string) (*Response, error)

Post performs an HTTP POST request with form data.

func (*Client) PostJSON

func (c *Client) PostJSON(rawURL string, params url.Values, body []byte) (*Response, error)

PostJSON performs an HTTP POST request with JSON body.

func (*Client) SetCookie

func (c *Client) SetCookie(cookie string)

SetCookie sets or replaces one cookie for subsequent requests.

func (*Client) SetCookies

func (c *Client) SetCookies(cookies map[string]string)

SetCookies sets or replaces named cookies for subsequent requests.

type ClientOption

ClientOption is a function that configures a Client.

type ClientOption func(*Client)

func WithJA3

func WithJA3(ja3 string) ClientOption

WithJA3 sets a custom JA3 fingerprint.

func WithTimeout

func WithTimeout(timeout int) ClientOption

WithTimeout sets the request timeout in seconds.

func WithUserAgent

func WithUserAgent(userAgent string) ClientOption

WithUserAgent sets a custom User-Agent.

type ErrorCode

ErrorCode represents the type of error.

type ErrorCode int

const (
    // ErrCodeUnknown is an unknown error.
    ErrCodeUnknown ErrorCode = iota
    // ErrCodeNetwork is a network-related error.
    ErrCodeNetwork
    // ErrCodeAuth is an authentication error.
    ErrCodeAuth
    // ErrCodeRateLimit is a rate limiting error (HTTP 429).
    ErrCodeRateLimit
    // ErrCodeNotFound is a not found error (HTTP 404).
    ErrCodeNotFound
    // ErrCodeInvalidSymbol is an invalid ticker symbol error.
    ErrCodeInvalidSymbol
    // ErrCodeInvalidResponse is an invalid response format error.
    ErrCodeInvalidResponse
    // ErrCodeNoData is a no data available error.
    ErrCodeNoData
    // ErrCodeTimeout is a request timeout error.
    ErrCodeTimeout
)

type Response

Response represents an HTTP response.

type Response struct {
    StatusCode int
    Body       string
    Headers    map[string]string
}

type YFError

YFError represents a Yahoo Finance API error.

type YFError struct {
    Code    ErrorCode
    Message string
    Cause   error
}

func HTTPStatusToError

func HTTPStatusToError(statusCode int, body string) *YFError

HTTPStatusToError converts an HTTP status code to an appropriate error.

func NewError

func NewError(code ErrorCode, message string, cause error) *YFError

NewError creates a new YFError.

func WrapAuthError

func WrapAuthError(err error) *YFError

WrapAuthError wraps an error as an authentication error.

func WrapInvalidResponseError

func WrapInvalidResponseError(err error) *YFError

WrapInvalidResponseError wraps an error as an invalid response error.

func WrapInvalidSymbolError

func WrapInvalidSymbolError(symbol string) *YFError

WrapInvalidSymbolError creates an invalid symbol error.

func WrapNetworkError

func WrapNetworkError(err error) *YFError

WrapNetworkError wraps an error as a network error.

func WrapNoDataError

func WrapNoDataError(symbol string) *YFError

WrapNoDataError creates a no data error for a symbol.

func WrapNotFoundError

func WrapNotFoundError(symbol string) *YFError

WrapNotFoundError creates a not found error for a symbol.

func WrapRateLimitError

func WrapRateLimitError() *YFError

WrapRateLimitError creates a rate limit error.

func WrapTimeoutError

func WrapTimeoutError(err error) *YFError

WrapTimeoutError wraps an error as a timeout error.

func (*YFError) Error

func (e *YFError) Error() string

Error implements the error interface.

func (*YFError) Is

func (e *YFError) Is(target error) bool

Is reports whether the error matches the target.

func (*YFError) Unwrap

func (e *YFError) Unwrap() error

Unwrap returns the underlying error.