Nothing
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Library General Public
# License as published by the Free Software Foundation; either
# version 2 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Library General Public License for more details.
#
# You should have received a copy of the GNU Library General
# Public License along with this library; if not, write to the
# Free Foundation, Inc., 59 Temple Place, Suite 330, Boston,
# MA 02111-1307 USA
################################################################################
# INTERNAL: DESCRIPTION:
# .getYahooData Downloads time series data from yahoo finance
################################################################################
.getYahooData <-
function(
symbol,
start = format(Sys.Date()-366, format = "%Y%m%d"),
end = format(Sys.Date(), format = "%Y%m%d"),
freq = c("daily", "weekly", "monthly"),
type = c("price", "split"),
adjust = TRUE,
quiet = TRUE)
{
# A copy of a function implemented by Josh Ulrich
# Description:
# Downloads time series data from yahoo finance
# Arguments:
# symbol - character, instrument symbol
# start - numeric, starting date, in ISO-8601 format as ccyymmdd,
# default is series' first date)
# end - numeric, ending date, in ISO-8601 format as ccyymmdd,
# default is today
# freq - character, frequency of data
# either 'daily', 'weekly', 'monthly'
# type - character, either 'price' or 'split'
# adjust - ogical, adjusts the Open, High, Low, and Close prices
# for dividends and splits, and adjusts Volume for dividends.
# References:
# http://help.yahoo.com/l/us/yahoo/finance/quotes
# http://help.yahoo.com/l/us/yahoo/finance/quotes/quote-12.html
# http://ichart.finance.yahoo.com/x?s=MSFT&g=d&y=0&z=30000
# Examples:
# ans = .getYahooData("IBM"); colnames(ans)
# "Date" "Open" "High" "Low" "Close" "Volume"
# "Unadj.Close" "Div" "Split" "Adj.Div"
# ans = .getYahooData("IBM", type = "split"); colnames(ans)
# "Date" "Div" "Split" "Adj.Div"
# Note:
# DW:
# This is Josh's function "getYahooData()" for udjusted prices and
# dividends+splits. We rename his function to ".getYahooData()"
# leave it untouched, and use the wrappers around it ...
# JU:
# Thank you to Giorgio Beltrame for the URL to download dividends
# _and_ splits, and for his correct adjustment procedure.
# Many thanks to Ion Georgiadis for helpful suggestions and testing.
# DW:
# Modifications:
# function renamed to .getYahooData
# description added
# examples added
# argument matching added
# attribute "update" added
# code shortened to max 80 characters per line
# Author:
# Package: TTR
# Type: Package
# Title: Technical Trading Rules
# Version: 0.14-0
# Date: 2008-01-23
# Author: Josh Ulrich
# Maintainer: Josh Ulrich <josh.m.ulrich@gmail.com>
# Enhances: quantmod
# Description: Functions and data to construct technical trading rules
# License: GPL-3
# FUNCTION:
# Match Arguments:
freq <- match.arg(freq)
type <- match.arg(type)
# Check Dates:
if (missing(start)) {
beg <- as.POSIXlt( "1900-01-01" )
} else {
beg <- as.POSIXlt( as.Date( as.character(start), "%Y%m%d" ) )
}
if (missing(end)) {
end <- as.POSIXlt(Sys.Date())
} else {
end <- as.POSIXlt( as.Date( as.character( end ), "%Y%m%d" ) )
}
if( beg > end ) stop("Start date must be before end date.")
if( beg > as.POSIXlt(Sys.Date()) ) stop("Start date is after today's date.")
# Get freqeucy and type parameters
freq <- match.arg( freq, c("daily","weekly","monthly") )
type <- match.arg( type, c("price","split") )
if(type == "price") {
freq.url <- substr(freq,1,1)
} else {
freq.url <- "v"
if(freq!="daily" & !quiet)
message("Only freq=\"daily\" data available for type=\"split\".\n",
"Setting freq=\"daily\"...")
}
flush.console()
if(type == "price") {
if(adjust) {
if(freq == "daily") {
# Get price, dividend, and split data from 'beg' to present
ohlc <- .getYahooData(symbol, start, freq="daily", type = "price",
adjust = FALSE, quiet = TRUE)
divspl <- .getYahooData(symbol, start, freq="daily", type = "split",
adjust = FALSE, quiet = TRUE)
ohlc <- merge(ohlc, divspl, by.col="Date", all = TRUE)
# Create split adjustment ratio, (always = 1 if no splits exist)
s.ratio <- rep(1, NROW(ohlc))
if( !all( is.na(ohlc$Split) ) ) {
# Start loop at most recent data
for( i in NROW(ohlc):2 ) {
if( is.na( ohlc$Split[i] ) ) {
s.ratio[i-1] <- s.ratio[i]
} else {
s.ratio[i-1] <- s.ratio[i] * ohlc$Split[i]
}
}
}
# Un-adjust dividends for Splits
ohlc$Div <- ohlc$Adj.Div * ( 1 / s.ratio )
# Create dividend adjustment ratio,
# (always = 1 if no dividends exist)
d.ratio <- rep(1, NROW(ohlc))
if( !all( is.na(ohlc$Adj.Div) ) ) {
# Start loop at most recent data
for( i in NROW(ohlc):2 ) {
if( is.na( ohlc$Adj.Div[i] ) ) {
d.ratio[i-1] <- d.ratio[i]
} else {
d.ratio[i-1] <- d.ratio[i] * ( 1 - ohlc$Div[i] /
ohlc$Close[i-1] )
}
}
}
# Adjust OHLC and volume
ohlc$Unadj.Close <- ohlc$Close
ohlc$Open <- ohlc$Open * d.ratio * s.ratio
ohlc$High <- ohlc$High * d.ratio * s.ratio
ohlc$Low <- ohlc$Low * d.ratio * s.ratio
ohlc$Close <- ohlc$Close * d.ratio * s.ratio
ohlc$Volume <- ohlc$Volume * ( 1 / d.ratio )
# Order columns
ohlc <- ohlc[,c("Date","Open","High","Low","Close","Volume",
"Unadj.Close","Div","Split","Adj.Div")]
} else {
stop("Only freq=\"daily\" adjusted data is currently supported.")
}
# For other frequencies, get daily data and use a routine to
# aggregate to desired frequency.
} else {
# Construct URL for 'beg' to 'end'
url <- paste(
"http://ichart.finance.yahoo.com/table.csv?s=", symbol,
"&a=", beg$mon,
"&b=", beg$mday,
"&c=", beg$year+1900,
"&d=", end$mon, "&e=", end$mday,
"&f=", end$year+1900,
"&g=", freq.url, "&ignore=.csv", sep="" )
# Fetch data:
ohlc <- read.table(url, header=TRUE, sep=",")
ohlc$Date <- as.Date(as.character(ohlc$Date), "%Y-%m-%d")
ohlc$Adj.Close <- NULL
}
} else {
if(!quiet)
message("Unadjusted and adjusted dividend data are always returned.")
# Construct URL for 'beg' to 'end'
url <- paste( "http://ichart.finance.yahoo.com/x?s=", symbol,
"&a=", beg$mon, "&b=", beg$mday, "&c=", beg$year+1900,
"&d=", end$mon, "&e=", end$mday, "&f=", end$year+1900,
"&g=", freq.url, "&y=0&z=30000", sep="" )
# Fetch data
ohlc <- read.table(url, skip=1, sep=",", fill=TRUE, as.is=TRUE)
div <- data.frame( Date= ohlc$V2[ohlc$V1=="DIVIDEND"],
Adj.Div=as.numeric(ohlc$V3[ohlc$V1=="DIVIDEND"]),
stringsAsFactors=FALSE )
spl <- data.frame( Date= ohlc$V2[ohlc$V1=="SPLIT"],
Split=as.character(ohlc$V3[ohlc$V1=="SPLIT"]),
stringsAsFactors=FALSE )
ohlc <- merge(div, spl, by.col="Date", all=TRUE)
ohlc$Date <- as.Date(as.character(ohlc$Date), "%Y%m%d")
# Create split adjustment ratio, (always = 1 if no splits exist)
s.ratio <- rep(1, NROW(ohlc))
if(NROW(spl)!=0) {
ohlc$Split <- sub(":","/", ohlc$Split)
ohlc$Split <- 1 / sapply( parse( text=ohlc$Split ), eval )
# Start loop at most recent data
for( i in NROW(ohlc):2 ) {
if( is.na( ohlc$Split[i] ) ) {
s.ratio[i-1] <- s.ratio[i]
} else {
s.ratio[i-1] <- s.ratio[i] * ohlc$Split[i]
}
}
}
# Un-adjust dividends for Splits
ohlc$Div <- ohlc$Adj.Div * ( 1 / s.ratio )
ohlc$Split <- as.numeric(ohlc$Split)
# Order data columns
ohlc <- ohlc[,c("Date","Div","Split","Adj.Div")]
# Return (empty) data
if(NROW(ohlc)==0) return(ohlc)
}
# Order Dates, and only return requested data (drop 'end' to present)
ohlc <- ohlc[order(ohlc$Date),]
row.names(ohlc) <- 1:NROW(ohlc)
ohlc <- ohlc[ ( ohlc$Date >= as.Date(beg) & ohlc$Date <= as.Date(end) ), ]
### Check to see if supplied dates occur in data set
if( max(ohlc$Date) != as.Date(end) ) {
if(!quiet) message("End date out of range, " , max(ohlc$Date),
" is last available date.")
}
if( min(ohlc$Date) != as.Date(beg) ) {
if(!quiet) message("Start date out of range, ", min(ohlc$Date),
" is first available date.")
}
# Add Attributes:
attr(ohlc, "update") <- format(Sys.time())
# Return Value:
return(ohlc)
}
###############################################################################
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.