YahooFinanceEx (YahooFinanceEx v0.4.0)

Copy Markdown View Source

Elixir client for Yahoo! Finance.

v0.4 surface:

  • get_quote/1 — single-symbol quote.
  • get_quotes/1 — batched quote fetch (up to 50 symbols per HTTP call; this function transparently batches larger lists).
  • get_fx_rate/2 — current FX rate between two ISO 4217 currency codes via Yahoo's <FROM><TO>=X quote symbol.
  • get_asset_profile/1 — sector + industry via the quoteSummary endpoint's assetProfile module (v0.3).
  • get_dividend_history/2 — per-payment dividend history via the chart endpoint's events=div stream (v0.3); the raw material for payment-schedule inference.
  • search/2 — free-text ticker/company autocomplete via the search endpoint (v0.4).

All paths go through YahooFinanceEx.Session to handle the cookie + CSRF crumb auth dance, and through Req for HTTP — so tests can stub the whole thing with Req.Test.

An in-memory cache layer is a planned follow-up.

Quickstart

{:ok, quote} = YahooFinanceEx.get_quote("AAPL")

{:ok, by_symbol} = YahooFinanceEx.get_quotes(["AAPL", "MSFT", "GOOG"])
by_symbol["AAPL"]
#=> {:ok, %YahooFinanceEx.Quote{symbol: "AAPL", ...}}

{:ok, rate} = YahooFinanceEx.get_fx_rate("EUR", "USD")
#=> {:ok, 1.08}

Notes

Yahoo's API is unofficial. Endpoints, auth requirements, and response shapes can change without notice. Two auth strategies are tried in order before erroring; sessions live for 60 seconds before being re-fetched.

Summary

Types

Errors returned by the public functions.

Per-symbol result inside a batched get_quotes/1 response.

One match returned by search/2.

Functions

Fetches the sector and industry for a ticker via Yahoo's quoteSummary endpoint (assetProfile module).

Fetches the per-payment dividend history for a ticker via the chart endpoint's events=div stream.

Fetches the current FX rate between two ISO 4217 currency codes — one unit of from expressed in to.

Fetches a single stock quote.

Fetches quotes for many symbols in one or more batched HTTP calls.

Searches Yahoo Finance for tickers matching a free-text query (a ticker fragment or a company name) via the /v1/finance/search autocomplete endpoint.

Types

error()

@type error() ::
  {:auth_failed, term()}
  | {:http_status, non_neg_integer()}
  | {:transport, term()}
  | :not_found

Errors returned by the public functions.

per_symbol_result()

@type per_symbol_result() :: {:ok, YahooFinanceEx.Quote.t()} | {:error, :not_found}

Per-symbol result inside a batched get_quotes/1 response.

search_result()

@type search_result() :: %{
  symbol: String.t(),
  name: String.t(),
  exchange: String.t() | nil,
  type: String.t() | nil
}

One match returned by search/2.

Functions

get_asset_profile(symbol)

@spec get_asset_profile(String.t()) ::
  {:ok, %{sector: String.t(), industry: String.t() | nil}} | {:error, error()}

Fetches the sector and industry for a ticker via Yahoo's quoteSummary endpoint (assetProfile module).

Returns {:ok, %{sector: sector, industry: industry}} (industry may be nil), or {:error, :not_found} for funds, ETFs, and any symbol where Yahoo exposes no asset profile (a blank sector counts as none — matching the Ruby client's behavior).

get_dividend_history(symbol, opts \\ [])

@spec get_dividend_history(
  String.t(),
  keyword()
) :: {:ok, [%{date: Date.t(), amount: float()}]} | {:error, error()}

Fetches the per-payment dividend history for a ticker via the chart endpoint's events=div stream.

Returns {:ok, entries} — each entry %{date: Date.t(), amount: float}, sorted ascending by date — or {:ok, []} when the symbol pays no dividends (or Yahoo reports none for the range). Consumers infer payment schedules (frequency, months) from these entries.

Options:

  • :range — Yahoo range string, default "2y" (enough to see a quarterly pattern twice).

get_fx_rate(currency, currency)

@spec get_fx_rate(String.t(), String.t()) :: {:ok, float()} | {:error, error()}

Fetches the current FX rate between two ISO 4217 currency codes — one unit of from expressed in to.

Returns {:ok, 1.0} for identity pairs without hitting the API. Returns {:ok, rate} (a float) on success, or {:error, reason} on failure (including :not_found when Yahoo has no quote for the pair).

get_quote(symbol)

@spec get_quote(String.t()) :: {:ok, YahooFinanceEx.Quote.t()} | {:error, error()}

Fetches a single stock quote.

Returns {:ok, %YahooFinanceEx.Quote{}} on success, or {:error, reason} with one of the error/0 shapes on failure.

Retries once on transient auth errors (Yahoo invalidates sessions occasionally); deeper failures bubble up.

get_quotes(symbols)

@spec get_quotes([String.t()]) ::
  {:ok, %{required(String.t()) => per_symbol_result()}} | {:error, error()}

Fetches quotes for many symbols in one or more batched HTTP calls.

Returns {:ok, results_map} where results_map is %{symbol => {:ok, Quote.t()} | {:error, :not_found}} — i.e. each requested symbol is present in the map, mapped to its individual result. Symbols Yahoo doesn't recognize come back as {:error, :not_found}.

Top-level errors ({:auth_failed, _}, {:transport, _}, etc.) abort the whole call and are returned as {:error, reason}.

Symbols are batched in groups of 50 (Yahoo's per-request ceiling). Duplicates and empty lists are tolerated.

search(query, opts \\ [])

@spec search(
  String.t(),
  keyword()
) :: {:ok, [search_result()]} | {:error, error()}

Searches Yahoo Finance for tickers matching a free-text query (a ticker fragment or a company name) via the /v1/finance/search autocomplete endpoint.

Returns {:ok, results} — each result %{symbol:, name:, exchange:, type:}, in Yahoo's relevance order — or {:ok, []} for a blank query or no matches. type is Yahoo's quoteType ("EQUITY", "ETF", "MUTUALFUND", "INDEX", …) so callers can filter to the instruments they care about; name falls back shortnamelongname → symbol.

Options:

  • :count — max results to request, default 10.