CI Hex.pm HexDocs

Elixir client for the Yahoo! Finance API. Handles Yahoo's cookie + CSRF crumb authentication transparently.

⚠️ Yahoo's API is unofficial and undocumented. Endpoints, auth requirements, and response shapes can change without notice. This library tracks the patterns that worked at the time of writing; expect occasional breakage.

Status

v0.2 surface:

  • get_quote/1 — single-symbol quote.
  • get_quotes/1 — batched quote fetch (chunks of 50, returns a per-symbol result map).
  • get_fx_rate/2 — FX rate between two ISO 4217 codes via the <FROM><TO>=X ticker convention.

Planned follow-ups (not yet implemented):

  • dividend history (get_dividend_history/2)
  • symbol search (search/2)
  • in-memory caching with TTL

Installation

def deps do
  [
    {:yahoo_finance_ex, "~> 0.2"}
  ]
end

Until published to Hex, use a git or path dependency:

def deps do
  [
    {:yahoo_finance_ex, github: "fleveque/yahoo_finance_ex"}
  ]
end

Usage

# Single symbol
{:ok, quote} = YahooFinanceEx.get_quote("AAPL")
quote.price            #=> 187.42

# Batched (chunks into groups of 50 internally)
{:ok, by_symbol} = YahooFinanceEx.get_quotes(["AAPL", "MSFT", "GOOG"])
by_symbol["AAPL"]      #=> {:ok, %YahooFinanceEx.Quote{...}}
by_symbol["FAKE"]      #=> {:error, :not_found}   # unknown symbols come back individually

# FX rate
{:ok, rate} = YahooFinanceEx.get_fx_rate("EUR", "USD")    #=> {:ok, 1.08}
{:ok, 1.0} = YahooFinanceEx.get_fx_rate("USD", "USD")     # identity short-circuits

Top-level errors (for get_quote and get_fx_rate, plus aborted get_quotes calls) return {:error, reason} with one of:

  • :not_found — Yahoo returned no quote for the symbol/pair
  • {:auth_failed, _} — auth refresh failed after retries
  • {:http_status, status} — non-200 HTTP status from Yahoo
  • {:transport, reason} — network / transport error from Req

For get_quotes/1, partial failures (some symbols missing) surface inside the result map as {:error, :not_found} for those keys; the top-level call still returns {:ok, map}.

Architecture

YahooFinanceEx           # public API
 Session              # GenServer: holds (cookie, crumb), refreshes on demand (60 s TTL)
 Quote                # struct returned by get_quote/1
 HTTP                 # private: wraps Req so tests can inject stubs

Session is started under the package's own supervisor as soon as :yahoo_finance_ex is started — no manual setup needed.

Testing your own code

All HTTP calls go through Req, so you can stub Yahoo's responses with Req.Test:

test "fetches a quote" do
  Req.Test.stub(YahooFinanceEx.HTTPStub, fn conn ->
    Req.Test.json(conn, %{
      "quoteResponse" => %{"result" => [%{"symbol" => "AAPL", "regularMarketPrice" => 187.42, ...}]}
    })
  end)

  # ...
end

See test/yahoo_finance_ex_test.exs for full setup including the Session GenServer's allowances.

License

MIT. See LICENSE.