[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