Packages

A simple elixir wrapper around Yahoo-Finance for historical and real-time stock quotes & data.

Current section

Files

Jump to
Raw

lib/quote.ex

defmodule YahooFinance.Quote do
import Utils
def get_full_quote(""), do:
{:error, "Cannot provide empty string as argument"}
def get_full_quote(symbol) when not is_string_like(symbol), do:
{:error, "Symbol argument must be given as string"}
def get_full_quote(symbol) do
request = request_quote(symbol)
case request.status_code do
200 -> {:ok, {symbol, request.body}}
_ -> "Error"
end
end
def get_simple_quote(""), do:
{:error, "Cannot provide empty string as argument"}
def get_simple_quote(symbol) when not is_string_like(symbol), do:
{:error, "Symbol argument must be given as string"}
def get_simple_quote(symbol) do
request = request_quote(symbol)
case request.status_code do
200 -> handle_quote_success(symbol, request.body)
_ -> "Error"
end
end
def get_custom_quote("", _), do:
{:error, "Cannot provide empty string as argument"}
def get_custom_quote(symbol, _args) when not is_string_like(symbol), do:
{:error, "Symbol argument must be given as string"}
def get_custom_quote(_symbol, args) when not is_list(args), do:
{:error, "Arguments must be given as list"}
def get_custom_quote(_symbol, []), do:
{:error, "List arguments must not be empty"}
def get_custom_quote(symbol, args) do
case valid_modules?(args) do
false ->
{:error, "One or more of modules entered is invalid"}
true ->
symbol
|> request_quote
|> handle_custom_quote(symbol, args)
end
end
defp request_quote(symbol) do
HTTPoison.get! "https://query1.finance.yahoo.com/v7/finance/quote?symbols=#{symbol}"
end
defp handle_custom_quote(results, symbol, args) do
case results.status_code do
200 -> handle_quote_success(symbol, results.body, args)
_ -> {:error, "Error with query..."}
end
end
defp handle_quote_success(symbol, data, args \\ get_simple_quote_args())
defp handle_quote_success(symbol, data, args) do
{_, results} = Poison.decode(data)
[quote_response] = results["quoteResponse"]["result"]
quote_data = args
|> Enum.map(fn(arg) -> Atom.to_string(arg) end)
|> Enum.reduce(%{}, fn(arg, acc) -> Map.merge(acc, %{arg => quote_response[arg]}) end)
|> encode
{:ok, {symbol, quote_data}}
end
defp encode(data) do
Poison.encode!(
%{
"quoteResponse" => %{
"result" => [data]
}
}
)
end
defp valid_modules?(args) do
modules = get_modules()
!Enum.any?(args, &(Enum.member?(modules, &1) == false))
end
defp get_simple_quote_args do
[
:regularMarketPrice,
:regularMarketChange,
:regularMarketOpen,
:regularMarketDayHigh,
:regularMarketDayLow,
:regularMarketPreviousClose,
:regularMarketVolume,
:bid,
:ask
]
end
defp get_modules do
[
:ask,
:askSize,
:averageDailyVolume10Day,
:averageDailyVolume3Month,
:bid,
:bidSize,
:bookValue,
:currency,
:earningsTimestamp,
:earningsTimestampEnd,
:earningsTimestampStart,
:epsForward,
:epsTrailingTwelveMonths,
:esgPopulated,
:exchange,
:exchangeDataDelayedBy,
:exchangeTimezoneName,
:exchangeTimezoneShortName,
:fiftyDayAverage,
:fiftyDayAverageChange,
:fiftyDayAverageChangePercent,
:fiftyTwoWeekHigh,
:fiftyTwoWeekHighChange,
:fiftyTwoWeekHighChangePercent,
:fiftyTwoWeekLow,
:fiftyTwoWeekLowChange,
:fiftyTwoWeekLowChangePercent,
:fiftyTwoWeekRange,
:financialCurrency,
:forwardPE,
:fullExchangeName,
:gmtOffSetMilliseconds,
:language,
:longName,
:market,
:marketCap,
:marketState,
:messageBoardId,
:postMarketChange,
:postMarketChangePercent,
:postMarketPrice,
:postMarketTime,
:priceHint,
:priceToBook,
:quoteSourceName,
:quoteType,
:regularMarketChange,
:regularMarketChangePercent,
:regularMarketDayHigh,
:regularMarketDayLow,
:regularMarketDayRange,
:regularMarketOpen,
:regularMarketPreviousClose,
:regularMarketPrice,
:regularMarketTime,
:regularMarketVolume,
:sharesOutstanding,
:shortName,
:sourceInterval,
:symbol,
:tradeable,
:trailingPE,
:twoHundredDayAverage,
:twoHundredDayAverageChange,
:twoHundredDayAverageChangePercent
]
end
end