Skip to content

Commit

Permalink
Update getQuote.yahoo to use JSON API
Browse files Browse the repository at this point in the history
Yahoo Finance deprecated the CSV-based quote API in favor of a JSON API
(similar to what they did with the historical data API in May, 2017).

Create a static matrix of yahoo quote field codes, names, and short
names. I did my best to map the old CSV fields to the new JSON fields.
Old fields that I could not find a new counterpart for are left as
comments, for future reference.

See #197.
  • Loading branch information
joshuaulrich committed Nov 14, 2017
1 parent b0ab966 commit c44f44f
Showing 1 changed file with 158 additions and 78 deletions.
236 changes: 158 additions & 78 deletions R/getQuote.R
Original file line number Diff line number Diff line change
Expand Up @@ -35,24 +35,37 @@ function(Symbols,what=standardQuote(),...) {
cat("...done\n")
return(df)
}
Symbols <- paste(strsplit(Symbols,';')[[1]],collapse="+")
Symbols <- paste(strsplit(Symbols,';')[[1]],collapse=',')
if(inherits(what, 'quoteFormat')) {
QF <- what[[1]]
QF.names <- what[[2]]
} else {
QF <- what
QF.names <- NULL
}
QF <- paste('d1t1',QF,sep='')
download.file(paste(
"https://finance.yahoo.com/d/quotes.csv?s=",
# JSON API currently returns the following fields with every request:
# language, quoteType, regularMarketTime, marketState, exchangeDataDelayedBy,
# exchange, fullExchangeName, market, sourceInterval, exchangeTimezoneName,
# exchangeTimezoneShortName, gmtOffSetMilliseconds, tradeable, symbol
QFc <- paste0(QF,collapse=',')
download.file(paste0(
"https://query1.finance.yahoo.com/v7/finance/quote?symbols=",
Symbols,
"&f=",QF,sep=""),
"&fields=",QFc),
destfile=tmp,quiet=TRUE)
sq <- read.csv(file=tmp,sep=',',stringsAsFactors=FALSE,header=FALSE)
Qposix <- strptime(paste(sq[,1],sq[,2]),format='%m/%d/%Y %H:%M')
Symbols <- unlist(strsplit(Symbols,'\\+'))
df <- data.frame(Qposix,sq[,3:NCOL(sq)])
# The 'response' data.frame has fields in columns and symbols in rows
response <- jsonlite::fromJSON(tmp)
if (is.null(response$quoteResponse$error)) {
sq <- response$quoteResponse$result
} else {
stop(response$quoteResponse$error)
}
# Always return symbol and time
#FIXME: use exchange TZ, if possible. POSIXct must have only one TZ, so
# times from different timezones will need to converted to a common TZ
Qposix <- .POSIXct(sq[,"regularMarketTime"], tz=NULL)
Symbols <- unlist(strsplit(Symbols,','))
df <- data.frame(Qposix, sq[,QF])
rownames(df) <- Symbols
if(!is.null(QF.names)) {
colnames(df) <- c('Trade Time',QF.names)
Expand Down Expand Up @@ -83,79 +96,20 @@ aq
}

`standardQuote.yahoo` <- function() {
yahooQF(names=c( "Last Trade (Price Only)",
"Change","Change in Percent",
"Open", "Days High", "Days Low", "Volume"))
yahooQF(names=c("Last Trade (Price Only)",
"Change","Change in Percent",
"Open", "Days High", "Days Low", "Volume"))
}

yahooQuote.EOD <- structure(list("ohgl1v", c("Open", "High",
"Low", "Close",
"Volume")), class="quoteFormat")

`yahooQF` <- function(names) {
optnames <- c("Ask", "Average Daily Volume", "Ask Size", "Bid", "Ask (Real-time)",
"Bid (Real-time)", "Book Value", "Bid Size", "Change & Percent Change",
"Change", "Commission", "Change (Real-time)", "After Hours Change (Real-time)",
"Dividend/Share", "Last Trade Date", "Trade Date", "Earnings/Share",
"Error Indication (returned for symbol changed / invalid)", "EPS Estimate Current Year",
"EPS Estimate Next Year", "EPS Estimate Next Quarter", "Float Shares",
"Days Low","Days High", "52-week Low", "52-week High", "Holdings Gain Percent",
"Annualized Gain", "Holdings Gain", "Holdings Gain Percent (Real-time)",
"Holdings Gain (Real-time)", "More Info", "Order Book (Real-time)",
"Market Capitalization", "Market Cap (Real-time)", "EBITDA",
"Change From 52-week Low", "Percent Change From 52-week Low",
"Last Trade (Real-time) With Time", "Change Percent (Real-time)",
"Last Trade Size", "Change From 52-week High", "Percent Change From 52-week High",
"Last Trade (With Time)", "Last Trade (Price Only)", "High Limit",
"Low Limit", "Days Range","Days Range (Real-time)", "50-day Moving Average",
"200-day Moving Average", "Change From 200-day Moving Average",
"Percent Change From 200-day Moving Average", "Change From 50-day Moving Average",
"Percent Change From 50-day Moving Average", "Name", "Notes",
"Open", "Previous Close", "Price Paid", "Change in Percent",
"Price/Sales", "Price/Book", "Ex-Dividend Date", "P/E Ratio",
"Dividend Pay Date", "P/E Ratio (Real-time)",
"PEG Ratio", "Price/EPS Estimate Current Year",
"Price/EPS Estimate Next Year", "Symbol", "Shares Owned", "Short Ratio",
"Last Trade Time", "Trade Links", "Ticker Trend", "1 yr Target Price",
"Volume", "Holdings Value", "Holdings Value (Real-time)", "52-week Range",
"Days Value Change", "Days Value Change (Real-time)", "Stock Exchange",
"Dividend Yield")
optshort <- c("Ask", "Ave. Daily Volume", "Ask Size", "Bid", "Ask (RT)",
"Bid (RT)", "Book Value", "Bid Size", "Change & % Change",
"Change", "Commission", "Change (RT)", "After Hours Change (RT)",
"Dividend/Share", "Last Trade Date", "Trade Date", "Earnings/Share",
"Error Indication (returned for symbol changed / invalid)",
"EPS Estimate Current Year",
"EPS Estimate Next Year", "EPS Estimate Next Quarter", "Float Shares",
"Low","High", "52-week Low", "52-week High", "Holdings Gain %",
"Annualized Gain", "Holdings Gain", "Holdings Gain % (RT)",
"Holdings Gain (RT)", "More Info", "Order Book (RT)",
"Market Capitalization", "Market Cap (RT)", "EBITDA",
"Change From 52-week Low", "% Change From 52-week Low",
"Last Trade (RT) With Time", "%Change (RT)",
"Last Size", "Change From 52-week High", "% Change From 52-week High",
"Last", "Last", "High Limit",
"Low Limit", "Days Range","Days Range (RT)", "50-day MA",
"200-day MA", "Change From 200-day MA",
"% Change From 200-day MA", "Change From 50-day MA",
"% Change From 50-day MA", "Name", "Notes",
"Open", "P. Close", "Price Paid", "% Change",
"Price/Sales", "Price/Book", "Ex-Dividend Date", "P/E Ratio",
"Dividend Pay Date", "P/E Ratio (RT)",
"PEG Ratio", "Price/EPS Estimate Current Year",
"Price/EPS Estimate Next Year", "Symbol", "Shares Owned", "Short Ratio",
"Last Trade Time", "Trade Links", "Ticker Trend", "1 yr Target Price",
"Volume", "Holdings Value", "Holdings Value (RT)", "52-week Range",
"Days Value Change", "Days Value Change (RT)", "Stock Exchange",
"Dividend Yield")
optcodes <- c("a", "a2", "a5", "b", "b2", "b3", "b4", "b6", "c", "c1", "c3",
"c6", "c8", "d", "d1", "d2", "e", "e1", "e7", "e8", "e9", "f6",
"g", "h", "j", "k", "g1", "g3", "g4", "g5", "g6", "i", "i5", "j1",
"j3", "j4", "j5", "j6", "k1", "k2", "k3", "k4", "k5", "l", "l1",
"l2", "l3", "m", "m2", "m3", "m4", "m5", "m6", "m7", "m8", "n", "n4",
"o", "p", "p1", "p2", "p5", "p6", "q", "r", "r1", "r2", "r5",
"r6", "r7", "s", "s1", "s7", "t1", "t6", "t7", "t8", "v", "v1",
"v7", "w", "w1", "w4", "x", "y")
optnames <- .yahooQuoteFields[,"name"]
optshort <- .yahooQuoteFields[,"shortname"]
optcodes <- .yahooQuoteFields[,"field"]

w <- NULL

if(!missing(names)) {
Expand All @@ -169,7 +123,133 @@ yahooQuote.EOD <- structure(list("ohgl1v", c("Open", "High",
w <- c(w,which(optnames %in% n))
}
}
str <- paste(optcodes[w],collapse='')
nms <- optshort[w]
return(structure(list(str,nms),class='quoteFormat'))
return(structure(list(optcodes[w], optshort[w]), class='quoteFormat'))
}

.yahooQuoteFields <-
matrix(c(
# quote / symbol
"Symbol", "Symbol", "symbol",
"Name", "Name", "shortName",
"Name (Long)", "NameLong", "longName",
"Quote Type", "Quote Type", "quoteType",
"Quote Source Name", "Quote Source", "quoteSourceName",
"Source Interval", "Source Interval", "sourceInterval",
"Currency", "Currency", "currency",
"Financial Currency", "Financial Currency", "financialCurrency",

# market / exchange
"Market", "Market", "market",
"Market State", "Market State", "marketState",
"Exchange", "Exchange", "exchange",
"Exchange Full Name", "Exchange Full Name", "fullExchangeName",
"Exchange Timezone", "Exchange Timezone", "exchangeTimezoneName",
"Exchange TZ", "Exchange TZ", "exchangeTimezoneShortName",
"Exchange Data Delay", "Exchange Data Delay", "exchangeDataDelayedBy",
"GMT Offset Millis", "GMT Offset", "gmtOffSetMilliseconds",
"Tradeable", "Tradeable", "tradeable",

# market data
"Ask", "Ask", "ask",
"Bid", "Bid", "bid",
"Ask Size", "Ask Size", "askSize",
"Bid Size", "Bid Size", "bidSize",
"Last Trade (Price Only)", "Last", "regularMarketPrice",
"Last Trade Time", "Last Trade Time", "regularMarketTime",
"Change", "Change", "regularMarketChange",
"Open", "Open", "regularMarketOpen",
"Days High", "High", "regularMarketDayHigh",
"Days Low", "Low", "regularMarketDayLow",
"Volume", "Volume", "regularMarketVolume",
"Change in Percent", "% Change", "regularMarketChangePercent",
"Previous Close", "P. Close", "regularMarketPreviousClose",
#"Trade Date", "Trade Date", "d2",
#"Last Trade Size", "Last Size", "k3",
#"Last Trade (Real-time) With Time", "Last Trade (RT) With Time", "k1",
#"Last Trade (With Time)", "Last", "l",
#"High Limit", "High Limit", "l2",
#"Low Limit", "Low Limit", "l3",
#"Order Book (Real-time)", "Order Book (RT)", "i5",
#"Days Range", "Days Range", "m",
#"Days Range (Real-time)", "Days Range (RT)", "m2",
#"52-week Range", "52-week Range", "w",

# trading stats
"Change From 52-week Low", "Change From 52-week Low", "fiftyTwoWeekLowChange",
"Percent Change From 52-week Low", "% Change From 52-week Low", "fiftyTwoWeekLowChangePercent",
"Change From 52-week High", "Change From 52-week High", "fiftyTwoWeekHighChange",
"Percent Change From 52-week High", "% Change From 52-week High", "fiftyTwoWeekHighChangePercent",
"52-week Low", "52-week Low", "fiftyTwoWeekLow",
"52-week High", "52-week High", "fiftyTwoWeekHigh",

"50-day Moving Average", "50-day MA", "fiftyDayAverage",
"Change From 50-day Moving Average", "Change From 50-day MA", "fiftyDayAverageChange",
"Percent Change From 50-day Moving Average", "% Change From 50-day MA", "fiftyDayAverageChangePercent",
"200-day Moving Average", "200-day MA", "twoHundredDayAverage",
"Change From 200-day Moving Average", "Change From 200-day MA", "twoHundredDayAverageChange",
"Percent Change From 200-day Moving Average", "% Change From 200-day MA", "twoHundredDayAverageChangePercent",

# valuation stats
"Market Capitalization", "Market Capitalization", "marketCap",
#"Market Cap (Real-time)", "Market Cap (RT)", "j3",
"P/E Ratio", "P/E Ratio", "trailingPE",
#"P/E Ratio (Real-time)", "P/E Ratio (RT)", "r2",
#"Price/EPS Estimate Current Year", "Price/EPS Estimate Current Year", "r6",
"Price/EPS Estimate Next Year", "Price/EPS Estimate Next Year", "forwardPE",
"Price/Book", "Price/Book", "priceToBook",
"Book Value", "Book Value", "bookValue",
#"Price/Sales", "Price/Sales", "p5",
#"PEG Ratio", "PEG Ratio", "r5",
#"EBITDA", "EBITDA", "j4",

# share stats
"Average Daily Volume", "Ave. Daily Volume", "averageDailyVolume3Month",
#"Average Daily Volume", "Ave. Daily Volume", "averageDailyVolume10Day",
"Shares Outstanding", "Shares Outstanding", "sharesOutstanding",
#"Float Shares", "Float Shares", "f6",
#"Short Ratio", "Short Ratio", "s7",

# dividends / splits
"Ex-Dividend Date", "Ex-Dividend Date", "dividendDate",
#"Dividend Pay Date", "Dividend Pay Date", "r1",
"Dividend/Share", "Dividend/Share", "trailingAnnualDividendRate",
"Dividend Yield", "Dividend Yield", "trailingAnnualDividendYield",

# earnings
"Earnings Timestamp", "Earnings Timestamp", "earningsTimestamp",
"Earnings Start Time", "Earnings Start Time", "earningsTimestampStart",
"Earnings End Time", "Earnings End Time", "earningsTimestampEnd",
"Earnings/Share", "Earnings/Share", "epsTrailingTwelveMonths",
"EPS Forward", "EPS Forward", "epsForward",
#"Earnings/Share", "Earnings/Share", "e",
#"EPS Estimate Current Year", "EPS Estimate Current Year", "e7",
#"EPS Estimate Next Year", "EPS Estimate Next Year", "e8",
#"EPS Estimate Next Quarter", "EPS Estimate Next Quarter", "e9",

# yahoo / meta
"Language", "Language", "language",
"Message Board ID", "Message Board ID", "messageBoardId",
"Price Hint", "Price Hint", "priceHint"

# user portfolio
#"Trade Links", "Trade Links", "t6",
#"Ticker Trend", "Ticker Trend", "t7",
#"1 yr Target Price", "1 yr Target Price", "t8",
#"Holdings Value", "Holdings Value", "v1",
#"Holdings Value (Real-time)", "Holdings Value (RT)", "v7",
#"Days Value Change", "Days Value Change", "w1",
#"Days Value Change (Real-time)", "Days Value Change (RT)", "w4",
#"Price Paid", "Price Paid", "p1",
#"Shares Owned", "Shares Owned", "s1",
#"Commission", "Commission", "c3",
#"Notes", "Notes", "n4",
#"More Info", "More Info", "i",
#"Annualized Gain", "Annualized Gain", "g3",
#"Holdings Gain", "Holdings Gain", "g4",
#"Holdings Gain Percent", "Holdings Gain %", "g1",
#"Holdings Gain Percent (Real-time)", "Holdings Gain % (RT)", "g5",
#"Holdings Gain (Real-time)", "Holdings Gain (RT)", "g6",

#"Error Indication (returned for symbol changed / invalid)", "Error Indication (returned for symbol changed / invalid)", "e1",
),
ncol = 3, byrow = TRUE, dimnames = list(NULL, c("name", "shortname", "field")))

0 comments on commit c44f44f

Please sign in to comment.