Elixir client for Yahoo! Finance.
v0.7 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>=Xquote symbol.get_asset_profile/1— company profile (sector, industry, website, description) via thequoteSummaryendpoint'sassetProfilemodule (v0.3; website + description added in v0.6).get_financial_data/1— leverage figures (total debt, debt/equity, current & quick ratio, cash, EBITDA) via thequoteSummaryendpoint'sfinancialDatamodule (v0.5).get_dividend_history/2— per-payment dividend history via the chart endpoint'sevents=divstream (v0.3); the raw material for payment-schedule inference.search/2— free-text ticker/company autocomplete via thesearchendpoint (v0.4).get_news/2— recent news headlines via thesearchendpoint'snewsstream (v0.6).get_price_history/2— monthly closing prices via the chart endpoint (the price series beside the dividend stream) (v0.7).
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 company profile 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 key leverage / balance-sheet figures for a ticker via the
quoteSummary endpoint (financialData module).
Fetches the current FX rate between two ISO 4217 currency codes — one
unit of from expressed in to.
Fetches recent news headlines for a ticker via Yahoo's
/v1/finance/search endpoint (its news stream).
Fetches the monthly closing-price history for a ticker via the chart endpoint (the price series alongside the dividend stream).
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
@type error() :: {:auth_failed, term()} | {:http_status, non_neg_integer()} | {:transport, term()} | :not_found
Errors returned by the public functions.
@type per_symbol_result() :: {:ok, YahooFinanceEx.Quote.t()} | {:error, :not_found}
Per-symbol result inside a batched get_quotes/1 response.
@type search_result() :: %{ symbol: String.t(), name: String.t(), exchange: String.t() | nil, type: String.t() | nil }
One match returned by search/2.
Functions
@spec get_asset_profile(String.t()) :: {:ok, %{ sector: String.t(), industry: String.t() | nil, website: String.t() | nil, description: String.t() | nil }} | {:error, error()}
Fetches the company profile for a ticker via Yahoo's quoteSummary
endpoint (assetProfile module).
Returns {:ok, %{sector:, industry:, website:, description:}} — industry,
website and description 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). description is
Yahoo's longBusinessSummary (English).
@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).
@spec get_financial_data(String.t()) :: {:ok, %{ total_debt: float() | nil, debt_to_equity: float() | nil, current_ratio: float() | nil, quick_ratio: float() | nil, total_cash: float() | nil, ebitda: float() | nil }} | {:error, error()}
Fetches key leverage / balance-sheet figures for a ticker via the
quoteSummary endpoint (financialData module).
Returns {:ok, %{total_debt, debt_to_equity, current_ratio, quick_ratio, total_cash, ebitda}} — each value a float or nil — or {:error, :not_found}
when Yahoo exposes no financialData (common for funds/ETFs and many
non-US tickers). debt_to_equity is Yahoo's percentage figure
(e.g. 151.4 = 151.4%).
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).
@spec get_news( String.t(), keyword() ) :: {:ok, [ %{ title: String.t(), url: String.t() | nil, publisher: String.t() | nil, published_at: DateTime.t() | nil } ]} | {:error, error()}
Fetches recent news headlines for a ticker via Yahoo's
/v1/finance/search endpoint (its news stream).
Returns {:ok, items} — each %{title:, url:, publisher:, published_at:}
with published_at a UTC DateTime (or nil), most-recent first — or
{:ok, []} when Yahoo returns no news.
Options:
:count— max headlines to request, default 8.
@spec get_price_history( String.t(), keyword() ) :: {:ok, [%{date: Date.t(), close: float()}]} | {:error, error()}
Fetches the monthly closing-price history for a ticker via the chart endpoint (the price series alongside the dividend stream).
Returns {:ok, entries} — each entry %{date: Date.t(), close: float},
sorted ascending by date, skipping months Yahoo reports as null — or
{:ok, []} when the symbol has no price data. Consumers use it (paired
with the dividend history) to build a historical yield band.
Options:
:range— Yahoo range string, default"6y"(enough for a ~5-year yield band plus a buffer).
@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.
@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.
@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 shortname →
longname → symbol.
Options:
:count— max results to request, default 10.