Sunday, February 2, 2014

Daily stock symbol reports with R

This is a simple R script that uses the quantmod package to look up stock symbols on Yahoo Finance, and the sendmailR package to send an email alert if the latest stock price ("Last" in the Yahoo report) is below a "buy" threshold or above a "sell" threshold.

The input file format is tab-delimited with three columns: Symbol, BuyAt, SellAt. There is no need for a header column. For example:
  AAPL        300     750
  BA           65      90
  ...

The function that does all the work is symbol.report. This reads the input file containing buy and sell thresholds, performs a Yahoo Finance query on all symbols in the file, and generates a dataframe with the details (BuyAt, SellAt, Open, Close, Last, etc) of every symbol whose latest price is either below the buy threshold, or above the sell threshold.

library(quantmod)
symbol.report <- function(filename, header=FALSE, sep = "\t") {
  watch.df <- read.delim(filename, header=header, sep=sep)
  colnames(watch.df) <- c('Symbol', 'BuyAt', 'SellAt')

  quote.df <- getQuote(paste(watch.df$Symbol, collapse=';'))
  quote.df$Symbol <- rownames(quote.df)

  df <- merge(watch.df, quote.df)

  df[(df$Last <= df$BuyAt) | (df$SellAt > 0 & df$Last >= df$SellAt), ]
}  

The symbol.report function is invoked by  symbol.alert, which will send an email to the provided address if the dataframe returned by symbol.report is not empty. If an email address is not provided, the dataframe will be printed to STDOUT.

library(sendmailR)
symbol.alert <- function(filename, email=NULL, verbose=FALSE) {
  df <- symbol.report(filename)

  if (nrow(df) == 0) {
    return(df)
  }

  if ( is.null(email) ) {
    print(df)
  } else {
    sendmail(# from: fake email address
             paste('<', "r.script@nospam.org", '>', sep=''),
             # to: provided email address
             paste('<', email, '>', sep=''),
             # subject
             "SYMBOL ALERT",
             # body
             capture.output(print(df, row.names=FALSE)),
             # SMTP server (gmail)
             control=list(smtpServer='ASPMX.L.GOOGLE.COM'),
             verbose=verbose)
  } 
  return(df)
}

A few things to note here:
  * a fake email address is used as the From address, allowing easy filtering of these emails
  * the SMTP server used is the GMail server, which may not be appropriate for some users

This function can be called from a shell script in a cron job, invoking R with the --vanilla option:

  R --vanilla -e "source('/home/me/symbol.alert.R'); ticker.email.alert('/home/me/monitoried_symbols.dat', 'me@gmail.com')"

And again, there is a github for the code.

No comments:

Post a Comment