[Blotter-commits] r481 - in pkg/FinancialInstrument: . R man
noreply at r-forge.r-project.org
noreply at r-forge.r-project.org
Fri Dec 3 20:32:58 CET 2010
Author: braverock
Date: 2010-12-03 20:32:58 +0100 (Fri, 03 Dec 2010)
New Revision: 481
Added:
pkg/FinancialInstrument/man/getSymbols.FI.Rd
pkg/FinancialInstrument/man/setSymbolLookup.FI.Rd
Modified:
pkg/FinancialInstrument/DESCRIPTION
pkg/FinancialInstrument/NAMESPACE
pkg/FinancialInstrument/R/instrument.R
pkg/FinancialInstrument/R/load.instruments.R
pkg/FinancialInstrument/R/synthetic.R
pkg/FinancialInstrument/man/instrument.Rd
pkg/FinancialInstrument/man/load.instruments.Rd
pkg/FinancialInstrument/man/synthetic.ratio.Rd
Log:
- add load.instrument, setSymbolLookup.FI, and getSymbols.FI methods
- update documentation
Modified: pkg/FinancialInstrument/DESCRIPTION
===================================================================
--- pkg/FinancialInstrument/DESCRIPTION 2010-11-30 14:16:16 UTC (rev 480)
+++ pkg/FinancialInstrument/DESCRIPTION 2010-12-03 19:32:58 UTC (rev 481)
@@ -1,7 +1,7 @@
Package: FinancialInstrument
Type: Package
Title: Financial Instrument Model Infrastructure for R
-Version: 0.2.1
+Version: 0.2.2
Date: $Date$
Author: Peter Carl, Dirk Eddelbuettel, Jeffrey Ryan, Joshua Ulrich,
Brian G. Peterson
@@ -9,6 +9,7 @@
Description: Infrastructure for defining instruments meta-data and
relationships. Provides support for multi-asset class and
multi-currency portfolios. Still in heavy development.
+URL: https://r-forge.r-project.org/projects/blotter/
License: GPL
LazyLoad: yes
Depends: R (>= 2.11.1), xts, zoo
Modified: pkg/FinancialInstrument/NAMESPACE
===================================================================
--- pkg/FinancialInstrument/NAMESPACE 2010-11-30 14:16:16 UTC (rev 480)
+++ pkg/FinancialInstrument/NAMESPACE 2010-12-03 19:32:58 UTC (rev 481)
@@ -9,10 +9,13 @@
export(currency)
export(is.currency)
export(exchange_rate)
+export(bond)
export(getInstrument)
-export(guaranteed_spread)
export(load.instruments)
+export(setSymbolLookup.FI)
+export(getSymbols.FI)
export(synthetic)
export(synthetic.ratio)
export(spread)
+export(guaranteed_spread)
export(volep)
Modified: pkg/FinancialInstrument/R/instrument.R
===================================================================
--- pkg/FinancialInstrument/R/instrument.R 2010-11-30 14:16:16 UTC (rev 480)
+++ pkg/FinancialInstrument/R/instrument.R 2010-12-03 19:32:58 UTC (rev 481)
@@ -37,7 +37,8 @@
#' This is robust enough if you take some care, though a more robust patch would be welcomed.
#'
#' The \code{primary_id} will be coerced within reason to a valid \R variable name by
-#' using \code{\link{make.names}} Please use some care to choose your primary identifiers so that R won't complain.
+#' using \code{\link{make.names}}. We also remove any leading digit (a simple workaround to account for issues with the Reuters API).
+#' Please use some care to choose your primary identifiers so that R won't complain.
#' If you have better regular expression code, we'd be happy to include it.
#'
#' Identifiers will also try to be discovered as regular named arguments passed in via \code{...}.
@@ -77,7 +78,8 @@
instrument<-function(primary_id , ..., currency , multiplier , tick_size=NULL, identifiers = NULL, type=NULL, assign_i=FALSE ){
if(is.null(primary_id)) stop("you must specify a primary_id for the instrument")
- #primary_id<-gsub("[+-=^%$@:;]",".",primary_id) # replace illegal characters
+ #deal with leading digits or illegal characters
+ if(is.numeric(substr(primary_id,1,1))) primary_id <- substr(primary_id,2,nchar(primary_id))
primary_id<-make.names(primary_id)
if(!is.currency(currency)) stop("currency ",currency," must be an object of type 'currency'")
@@ -88,7 +90,7 @@
} else {
arg<-list(...)
#check for identifiers we recognize
- ident_str<-c("X.RIC","CUSIP","SEDOL","OSI","Bloomberg","Reuters","ISIN","CQG","TT","Yahoo","Google")
+ ident_str<-c("X.RIC","RIC","CUSIP","SEDOL","OSI","Bloomberg","Reuters","ISIN","CQG","TT","Yahoo","Google")
for(i_s in ident_str ){
if(any(grepl(i_s,names(arg),ignore.case=TRUE))) {
pos<-first(grep(i_s,names(arg),ignore.case=TRUE))
@@ -159,14 +161,15 @@
## with futures series we probably need to be more sophisticated,
## and find the existing series from prior periods (probably years or months)
## and then add the first_traded and expires to the time series bu splicing
- temp_series<-try(getInstrument(paste(primary_id, suffix_id,sep="_")),silent=TRUE)
+ id<-paste(primary_id, suffix_id,sep="_")
+ temp_series<-try(getInstrument(id),silent=TRUE)
if(inherits(temp_series,"future_series")) {
- message("updating existing first_traded and expires")
+ message("updating existing first_traded and expires for ",id)
temp_series$first_traded<-c(temp_series$first_traded,first_traded)
temp_series$expires<-c(temp_series$expires,expires)
- assign(paste(primary_id, suffix_id, sep="_"), temp_series, envir=as.environment(.instrument))
+ assign(id, temp_series, envir=as.environment(.instrument))
} else {
- temp_series = instrument( primary_id = paste(contract$primary_id,suffix_id,sep='_'),
+ temp_series = instrument( primary_id = id,
suffix_id=suffix_id,
currency = contract$currency,
multiplier = contract$multiplier,
@@ -202,14 +205,15 @@
## and find the existing series from prior periods (probably years)
## and then add the first_traded and expires to the time series
if(length(callput)==2) stop("value of callput must be specified as 'call' or 'put'")
- temp_series<-try(getInstrument(paste(primary_id, suffix_id,sep="_")),silent=TRUE)
+ id<-paste(primary_id, suffix_id,sep="_")
+ temp_series<-try(getInstrument(id),silent=TRUE)
if(inherits(temp_series,"option_series")) {
- message("updating existing first_traded and expires")
+ message("updating existing first_traded and expires for ", id)
temp_series$first_traded<-c(temp_series$first_traded,first_traded)
temp_series$expires<-c(temp_series$expires,expires)
- assign(paste(primary_id, suffix_id,sep="_"), temp_series, envir=as.environment(.instrument))
+ assign(id, temp_series, envir=as.environment(.instrument))
} else {
- temp_series = instrument( primary_id = paste(contract$primary_id,suffix_id,sep='_'),
+ temp_series = instrument( primary_id = id,
suffix_id = suffix_id,
currency = contract$currency,
multiplier = contract$multiplier,
@@ -265,6 +269,7 @@
}
#TODO auction dates, coupons, etc for govmt. bonds
+#' @export
bond <- function(primary_id , currency , multiplier, tick_size=NULL , identifiers = NULL, ...){
bond_temp = instrument(primary_id=primary_id , currency=currency , multiplier=multiplier , tick_size=tick_size, identifiers = identifiers, ..., type="bond", assign_i=TRUE )
}
Modified: pkg/FinancialInstrument/R/load.instruments.R
===================================================================
--- pkg/FinancialInstrument/R/load.instruments.R 2010-11-30 14:16:16 UTC (rev 480)
+++ pkg/FinancialInstrument/R/load.instruments.R 2010-12-03 19:32:58 UTC (rev 481)
@@ -28,9 +28,9 @@
#'
#' Typically, columns will exist for \code{multiplier} and \code{tick_size}.
#'
-#' Any other columns necessary to define the specified instrument type will also be required to avoid Errors.
+#' Any other columns necessary to define the specified instrument type will also be required to avoid fatal Errors.
#'
-#' Additional columns will be processed, either as additional identifiers for recognized identifier names, or as custom feilds. See \code{\link{instrument}} for more information on custom fields.
+#' Additional columns will be processed, either as additional identifiers for recognized identifier names, or as custom fields. See \code{\link{instrument}} for more information on custom fields.
#'
#' @param file string identifying file to load, default NULL, see Details
#' @param ... any other passthru parameters
@@ -84,21 +84,50 @@
arg$type<-NULL
arg<-arg[!is.na(arg)]
arg<-arg[!arg==""]
- if (set_primary) arg$primary_id<-filedata[rn,id_col]
- out<-try(do.call(type,arg))
+ if (set_primary) {
+ arg$primary_id<-filedata[rn,id_col]
+ }
+
+ if(is.function(try(match.fun(type)))){
+ out <- try(do.call(type,arg))
+ }
if(inherits(out,"try-error")){
+ # the call for a function named for type didn't work, so we'll try calling instrument as a generic
type=c(type,"instrument")
- arg$type<-type
- try(do.call("instrument",args))
+ arg$type<-type # set the type
+ arg$assign_i<-TRUE # assign to the environment
+ try(do.call("instrument",arg))
}
} else {
warning(filedata[rn,id_col],"already exists in the .instrument environment")
}
}
-
}
-setSymbolLookup.FI<-function(base_dir,storage_method='rda',split_method=c("days","common")){
+#' set quantmod-style SymbolLookup for instruments
+#'
+#' This function exists to tell \code{\link[quantmod]{getSymbols}} where to look for your repository of market data.
+#'
+#' The \code{base_dir} parameter \emph{must} be set or the function will fail.
+#' This will vary by your local environment and operating system. For mixed-OS environments,
+#' we recommend doing some OS-detection and setting the network share to your data to a common
+#' location by operating system. For example, all Windows machines may use \dQuote{M:/}
+#' and all *nix-style (linux, Mac) machines may use \dQuote{/mnt/mktdata/}.
+#'
+#' The \code{split_method} currently allows either \sQuote{days} or \sQuote{common}, and expects the
+#' file or files to be in sub-directories named for the symbol. In high frequency data, it is standard practice to split
+#' the data by days, which is why that option is the default.
+#'
+#' @param base_dir string specifying the base directory where data is stored, see Details
+#' @param storage_method currently only \sQuote{rda}, but we will eventually support \sQuote{indexing} at least, and maybe others
+#' @param split_method string specifying the method files are split, currently \sQuote{days} or \sQuote{common}, see Details
+#' @param ... any other passthru parameters
+#' @param extension file extension, default "rda"
+#' @seealso
+#' \code{\link{load.instruments}}
+#' \code{\link[quantmod]{setSymbolLookup}}
+#' @export
+setSymbolLookup.FI<-function(base_dir,..., split_method=c("days","common"), storage_method='rda', use_identifier='primary_id', extension='rda'){
# check that base_dir exists
if(!file.exists(base_dir)) stop('base_dir ',base_dir,' does not seem to specify a valid path' )
@@ -111,21 +140,54 @@
#initialize list
params<-list()
params$storage_method<-storage_method
- if(storage_method=='rda') params$extension<-'rda'
+ params$extension<-extension
params$split_method<-split_method
params$src<-"FI"
new.symbols<-list()
+ ndc<-nchar(base_dir)
+ if(substr(base_dir,ndc,ndc)=='/') sepch='' else sepch='/'
for (instr in instr_names){
+ if(!use_identifier=='primary_id'){
+ tmp_instr<-getInstrument(instr)
+ instr_str<-tmp_instr$identifiers[[use_identifier]]
+ if(!is.null(instr_str)) instr<-instr_str
+ else {
+ instr_str<-tmp_instr[[use_identifier]]
+ if(!is.null(instr_str)) instr<-instr_str
+ }
+ }
symbol<-list()
symbol[[1]]<-params
- # construct $dir
- symbol[[1]]$dir<-paste(base_dir,instr,sep="/")
+ # construct $dir
+ symbol[[1]]$dir<-paste(base_dir,instr,sep=sepch)
names(symbol)[1]<-instr
new.symbols<-c(new.symbols,symbol)
}
setSymbolLookup(new.symbols)
}
+#' getSymbols method for loading data from split files
+#'
+#' This function should probably get folded back into getSymbols.rda in quantmod.
+#'
+#' Meant to be called internally by \code{\link[quantmod]{getSymbols}} .
+#'
+#' The symbol lookup table will most likely be loaded by \code{\link{setSymbolLookup.FI}}
+#'
+#' @param Symbols a character vector specifying the names of each symbol to be loaded
+#' @param from Retrieve data no earlier than this date. Default '2010-01-01'.
+#' @param to Retrieve data through this date. Default Sys.Date().
+#' @param ... any other passthru parameters
+#' @param env where to create objects. Default .GlobalEnv
+#' @param dir if not specified in getSymbolLookup, directory string to use. default ""
+#' @param return.class only "xts" is currently supported
+#' @param extension file extension, default "rda"
+#' @param date_format format as per the \code{\link{strptime}}, default '\%Y.\%m.\%d'
+#' @seealso
+#' \code{\link{setSymbolLookup.FI}}
+#' \code{\link{load.instruments}}
+#' \code{\link[quantmod]{getSymbols}}
+#' @export
getSymbols.FI <- function(Symbols,
from='2010-01-01',
to=Sys.Date(),
@@ -133,7 +195,8 @@
env,
dir="",
return.class="xts",
- extension="rda"
+ extension="rda",
+ date_format='%Y.%m.%d'
)
{
importDefaults("getSymbols.FI")
@@ -168,11 +231,9 @@
EndDate <- as.Date(to)
date.vec <- as.Date(StartDate:EndDate)
- date.vec.ch <- as.character(date.vec)
-
for(d in date.vec) {
if(weekdays(as.Date(d)) == "Saturday" || weekdays(as.Date(d)) == "Sunday"){next}
- d<-format(as.Date(d),format='%Y.%m.%d')
+ d<-format(as.Date(d),format=date_format)
if(dir=="") {
sym.file <- paste(d,Symbols[[i]],extension,sep=".")
} else {
@@ -183,8 +244,10 @@
next
}
local.name <- load(sym.file)
- if(!is.null(fr)) local.name<-rbind(fr,local.name)
- assign('fr',get(local.name))
+ if(!is.null(fr)) {
+ fr<-rbind(fr,get(local.name))
+ } else assign('fr',get(local.name))
+ rm(local.name)
} # end date loop
},
common = , {
@@ -201,11 +264,11 @@
local.name <- load(sym.file)
assign('fr',get(local.name))
if(verbose) cat("done.\n")
- if(!is.xts(fr)) fr <- xts(fr[,-1],as.Date(fr[,1],origin='1970-01-01'),src='rda',updated=Sys.time())
+ #if(!is.xts(fr)) fr <- xts(fr[,-1],as.Date(fr[,1],origin='1970-01-01'),src='rda',updated=Sys.time())
} # end 'common'/default method (same as getSymbols.rda)
) # end split_method switch
fr <- quantmod:::convert.time.series(fr=fr,return.class=return.class)
- Symbols[[i]] <-make.names(Symbols[[ii]])
+ Symbols[[i]] <-make.names(Symbols[[i]])
if(auto.assign) assign(Symbols[[i]],fr,env)
if(verbose) cat("done.\n")
} #end loop over Symbols
Modified: pkg/FinancialInstrument/R/synthetic.R
===================================================================
--- pkg/FinancialInstrument/R/synthetic.R 2010-11-30 14:16:16 UTC (rev 480)
+++ pkg/FinancialInstrument/R/synthetic.R 2010-12-03 19:32:58 UTC (rev 481)
@@ -18,6 +18,18 @@
}
#' constructors for synthetic instruments
+#'
+#' Simple derivatives like \code{\link{option}} or \code{\link{future}} contracts typically have one underlying instrument.
+#' While properties like strike and expiration vary for these derivative contracts or series, the underlying is well understood.
+#'
+#' More complex derivatives are typically modeled as baskets of underlying products, and are typically traded over-the-counter or as proprietary in-house products.
+#'
+#' The general \code{synthetic} function is intended to be extended to support these arbitrary baskets of assets.
+#'
+#' Currently implemented examples are in ratio based spreads in \code{spread} and in exchange-guaranteed spread products in \code{guaranteed_spread}.
+#'
+#' We welcome assistance from others to model more complex OTC derivatives such as swap products.
+#'
#' @param primary_id string describing the unique ID for the instrument
#' @param currency string describing the currency ID of an object of type \code{\link{currency}}
#' @param multiplier numeric multiplier to apply to the price in the instrument currency to get to notional value
Added: pkg/FinancialInstrument/man/getSymbols.FI.Rd
===================================================================
--- pkg/FinancialInstrument/man/getSymbols.FI.Rd (rev 0)
+++ pkg/FinancialInstrument/man/getSymbols.FI.Rd 2010-12-03 19:32:58 UTC (rev 481)
@@ -0,0 +1,24 @@
+\name{getSymbols.FI}
+\alias{getSymbols.FI}
+\title{getSymbols method for loading data from split files...}
+\usage{getSymbols.FI(Symbols, from="2010-01-01", to=Sys.Date(), ..., env,
+ dir="", return.class="xts", extension="rda",
+ date_format="\%Y.\%m.\%d")}
+\description{getSymbols method for loading data from split files}
+\details{This function should probably get folded back into getSymbols.rda in quantmod.
+
+Meant to be called internally by \code{\link[quantmod]{getSymbols}} .
+
+The symbol lookup table will most likely be loaded by \code{\link{setSymbolLookup.FI}}}
+\seealso{\code{\link{setSymbolLookup.FI}}
+\code{\link{load.instruments}}
+\code{\link[quantmod]{getSymbols}}}
+\arguments{\item{Symbols}{a character vector specifying the names of each symbol to be loaded}
+\item{from}{Retrieve data no earlier than this date. Default '2010-01-01'.}
+\item{to}{Retrieve data through this date. Default Sys.Date().}
+\item{...}{any other passthru parameters}
+\item{env}{where to create objects. Default .GlobalEnv}
+\item{dir}{if not specified in getSymbolLookup, directory string to use. default ""}
+\item{return.class}{only "xts" is currently supported}
+\item{extension}{file extension, default "rda"}
+\item{date_format}{format as per the \code{\link{strptime}}, default '\%Y.\%m.\%d'}}
Modified: pkg/FinancialInstrument/man/instrument.Rd
===================================================================
--- pkg/FinancialInstrument/man/instrument.Rd 2010-11-30 14:16:16 UTC (rev 480)
+++ pkg/FinancialInstrument/man/instrument.Rd 2010-12-03 19:32:58 UTC (rev 481)
@@ -15,7 +15,8 @@
This is robust enough if you take some care, though a more robust patch would be welcomed.
The \code{primary_id} will be coerced within reason to a valid \R variable name by
-using \code{\link{make.names}} Please use some care to choose your primary identifiers so that R won't complain.
+using \code{\link{make.names}}. We also remove any leading digit (a simple workaround to account for issues with the Reuters API).
+Please use some care to choose your primary identifiers so that R won't complain.
If you have better regular expression code, we'd be happy to include it.
Identifiers will also try to be discovered as regular named arguments passed in via \code{...}.
Modified: pkg/FinancialInstrument/man/load.instruments.Rd
===================================================================
--- pkg/FinancialInstrument/man/load.instruments.Rd 2010-11-30 14:16:16 UTC (rev 480)
+++ pkg/FinancialInstrument/man/load.instruments.Rd 2010-12-03 19:32:58 UTC (rev 481)
@@ -17,9 +17,9 @@
Typically, columns will exist for \code{multiplier} and \code{tick_size}.
-Any other columns necessary to define the specified instrument type will also be required to avoid Errors.
+Any other columns necessary to define the specified instrument type will also be required to avoid fatal Errors.
-Additional columns will be processed, either as additional identifiers for recognized identifier names, or as custom feilds. See \code{\link{instrument}} for more information on custom fields.}
+Additional columns will be processed, either as additional identifiers for recognized identifier names, or as custom fields. See \code{\link{instrument}} for more information on custom fields.}
\seealso{instrument}
\arguments{\item{file}{string identifying file to load, default NULL, see Details}
\item{...}{any other passthru parameters}
Added: pkg/FinancialInstrument/man/setSymbolLookup.FI.Rd
===================================================================
--- pkg/FinancialInstrument/man/setSymbolLookup.FI.Rd (rev 0)
+++ pkg/FinancialInstrument/man/setSymbolLookup.FI.Rd 2010-12-03 19:32:58 UTC (rev 481)
@@ -0,0 +1,24 @@
+\name{setSymbolLookup.FI}
+\alias{setSymbolLookup.FI}
+\title{set quantmod-style SymbolLookup for instruments...}
+\usage{setSymbolLookup.FI(base_dir, ..., split_method=c("days", "common"),
+ storage_method="rda", use_identifier="primary_id", extension="rda")}
+\description{set quantmod-style SymbolLookup for instruments}
+\details{This function exists to tell \code{\link[quantmod]{getSymbols}} where to look for your repository of market data.
+
+The \code{base_dir} parameter \emph{must} be set or the function will fail.
+This will vary by your local environment and operating system. For mixed-OS environments,
+we recommend doing some OS-detection and setting the network share to your data to a common
+location by operating system. For example, all Windows machines may use \dQuote{M:/}
+and all *nix-style (linux, Mac) machines may use \dQuote{/mnt/mktdata/}.
+
+The \code{split_method} currently allows either \sQuote{days} or \sQuote{common}, and expects the
+file or files to be in sub-directories named for the symbol. In high frequency data, it is standard practice to split
+the data by days, which is why that option is the default.}
+\seealso{\code{\link{load.instruments}}
+\code{\link[quantmod]{setSymbolLookup}}}
+\arguments{\item{base_dir}{string specifying the base directory where data is stored, see Details}
+\item{storage_method}{currently only \sQuote{rda}, but we will eventually support \sQuote{indexing} at least, and maybe others}
+\item{split_method}{string specifying the method files are split, currently \sQuote{days} or \sQuote{common}, see Details}
+\item{...}{any other passthru parameters}
+\item{extension}{file extension, default "rda"}}
Modified: pkg/FinancialInstrument/man/synthetic.ratio.Rd
===================================================================
--- pkg/FinancialInstrument/man/synthetic.ratio.Rd 2010-11-30 14:16:16 UTC (rev 480)
+++ pkg/FinancialInstrument/man/synthetic.ratio.Rd 2010-12-03 19:32:58 UTC (rev 481)
@@ -4,9 +4,20 @@
type=c("synthetic.ratio", "synthetic", "instrument"), members,
memberratio)}
\description{constructors for synthetic instruments}
+\details{Simple derivatives like \code{\link{option}} or \code{\link{future}} contracts typically have one underlying instrument.
+While properties like strike and expiration vary for these derivative contracts or series, the underlying is well understood.
+
+More complex derivatives are typically modeled as baskets of underlying products, and are typically traded over-the-counter or as proprietary in-house products.
+
+The general \code{synthetic} function is intended to be extended to support these arbitrary baskets of assets.
+
+Currently implemented examples are in ratio based spreads in \code{spread} and in exchange-guaranteed spread products in \code{guaranteed_spread}.
+
+We welcome assistance from others to model more complex OTC derivatives such as swap products.}
\alias{synthetic}
\alias{spread}
\alias{synthetic.ratio}
+\alias{guaranteed_spread}
\arguments{\item{primary_id}{string describing the unique ID for the instrument}
\item{currency}{string describing the currency ID of an object of type \code{\link{currency}}}
\item{multiplier}{numeric multiplier to apply to the price in the instrument currency to get to notional value}
More information about the Blotter-commits
mailing list