[Blotter-commits] r232 - in pkg/quantstrat: R man

noreply at r-forge.r-project.org noreply at r-forge.r-project.org
Sat Feb 6 15:13:23 CET 2010


Author: braverock
Date: 2010-02-06 15:13:22 +0100 (Sat, 06 Feb 2010)
New Revision: 232

Added:
   pkg/quantstrat/R/rules.R
   pkg/quantstrat/man/applyRules.Rd
Modified:
   pkg/quantstrat/R/indicators.R
   pkg/quantstrat/R/signals.R
   pkg/quantstrat/man/applySignals.Rd
Log:
- applyRules template function
- more documentation
- minor bugfixes

Modified: pkg/quantstrat/R/indicators.R
===================================================================
--- pkg/quantstrat/R/indicators.R	2010-02-06 12:11:21 UTC (rev 231)
+++ pkg/quantstrat/R/indicators.R	2010-02-06 14:13:22 UTC (rev 232)
@@ -95,7 +95,7 @@
         #print(tmp_val)
     } #end indicators loop
     if(is.null(ret)) return(mktdata)
-    else return(list(mktdata=mktdata,indicator_ret=ret))
+    else return(ret)
 }
 
 

Copied: pkg/quantstrat/R/rules.R (from rev 231, pkg/quantstrat/R/traderules.R)
===================================================================
--- pkg/quantstrat/R/rules.R	                        (rev 0)
+++ pkg/quantstrat/R/rules.R	2010-02-06 14:13:22 UTC (rev 232)
@@ -0,0 +1,181 @@
+#' add a rule to a strategy
+#' 
+#' Rules will be processed in a very particular manner, so it bears going over.
+#' 
+#' First, rules are either path dependent or non-path-dependent.  Path dependent rules 
+#' will be processed in every time increment for the \code{mktdata} passed into
+#' \code{\link{applyStrategy}}.  Non path dependent rules will likely be quite rare in real life, 
+#' and will be applied after indicators and signals, and before path-dependent rules are processed.
+#' 
+#' All rules have a \code{type}.  These may be any of:
+#' \itemize{
+#'   \item{risk}{ rules that check and react to risk of positions, may stop all other rule execution temporarily or permanently}
+#'   \item{order}{ rules for order processing of any open orders at time t, always path-dependent}
+#'   \item{rebalance}{ rules executed specifically in a portfolio context, unnecessary in univariate strategies}
+#'   \item{exit}{ rules to determine whether to exit a position}
+#'   \item{enter}{ rules to determine whether to enter or increase a position}
+#' }  
+#' The rules will be executed by type, in the order listed above.  
+#' Multiple rules of each type may be defined, as with signals and indicators, 
+#' they will be executed in order by index number with any other rules sharing the same 
+#' type.
+#' 
+#' The rule execution order was constructed because path-dependent rules may modify   
+#' the ability of rules that have not fired yet to be evaluated.  For example, a 
+#' risk rule may flatten (close out) an entire position and put new orders 
+#' on hold, effectively stopping all further execution of the strategy.  
+#' Another example would be a rebalancing rule function that would enter 
+#' orders to rebalance the portfolio, and would hold other strategy processing 
+#' until the rebalancing period was over.
+#' 
+#' We anticipate that rules will be the portion of a strategy most likely to 
+#' not have suitable template code included with this package, as every strategy 
+#' and environment are different, especially in this respect.  
+#' We will attempt to provide enough examples and generic rules to give strategy
+#' authors a place to start.
+#'    
+#' @param strategy an object of type 'strategy' to add the rule to
+#' @param name name of the rule, must correspond to an R function
+#' @param arguments default arguments to be passed to an rule function when executed
+#' @param label arbitrary text label for signal output, NULL default will be converted to '<name>.sig'
+#' @param type one of "risk","order","rebalance","exit","entry", see Details
+#' @param ... any other passthru parameters
+#' @param enabled TRUE/FALSE whether the rule is enabled for use in applying the strategy, default TRUE
+#' @param indexnum if you are updating a specific rule, the index number in the $rules[type] list to update
+#' @param path.dep TRUE/FALSE whether rule is path dependent, default TRUE, see Details 
+#' @param store TRUE/FALSE whether to store the strategy in the .strategy environment, or return it.  default FALSE
+#' @export
+add.rule <- function(strategy, name, arguments, label=NULL, type=c(NULL,"risk","order","rebalance","exit","entry"), ..., enabled=TRUE, indexnum=NULL, path.dep=TRUE, store=FALSE) {
+    if(!is.strategy(strategy)) stop("You must pass in a strategy object to manipulate")
+    type=type[1]
+    if(is.null(type)) stop("You must specify a type")
+    tmp_rule<-list()
+    tmp_rule$name<-name
+    tmp_rule$type<-type
+    # TODO change this to a separate slot!!!!!
+    tmp_rule$enabled<-enabled
+    if (!is.list(arguments)) stop("arguments must be passed as a named list")
+    arguments$label=label
+    tmp_rule$arguments<-arguments
+    if(!hasArg(indexnum) | (hasArg(indexnum) & is.null(indexnum))) indexnum = length(strategy$rules[type])+1
+    tmp_rule$call<-match.call()
+    strategy$rules[type][[indexnum]]<-tmp_rule
+    
+    if (store) assign(strategy$name,strategy,envir=as.environment(.strategy))
+    else return(strategy)
+}
+
+#' apply the rules in the strategy to arbitrary market data 
+#' 
+#' In typical usage, this function will be called via \code{\link{applyStrategy}}.  In this mode, this function will be called twice, once with \code{path.dep=FALSE} and then again in stepping over the .
+#' @param strategy an object of type 'strategy' to add the rule to
+#' @param mktdata an xts object containing market data.  depending on rules, may need to be in OHLCV or BBO formats, and may include indicator and signal information
+#' @param indicators if indicator output is not contained in the mktdata object, it may be passed separately as an xts object or a list.
+#' @param signals if signal output is not contained in the mktdata object, it may be passed separately as an xts object or a list.
+#' @param ... any other passthru parameters
+#' @param path.dep TRUE/FALSE whether rule is path dependent, default TRUE, see Details 
+#' @seealso \code{\link{add.rule}} \code{\link{applyStrategy}} 
+#' @export
+applyRules <- function(strategy, mktdata, indicators=NULL, signals=NULL, ..., path.dep=TRUE) {
+    #TODO add Date subsetting
+    
+    # TODO check for symbol name in mktdata using Josh's code:
+    # symbol <- strsplit(colnames(mktdata)[1],"\\.")[[1]][1]
+    
+    # TODO handle indicator and signal lists as well as indicators/signals that were cbound to mktdata
+    
+    if (!is.strategy(strategy)) {
+        strategy<-try(getStrategy(strategy))
+        if(inherits(strategy,"try-error"))
+            stop ("You must supply an object of type 'strategy'.")
+    } 
+    ret <- NULL
+    nargs <-list(...)
+    if(length(nargs)==0) nargs=NULL
+    if (length('...')==0 | is.null('...')) {
+        rm('...')
+        nargs=NULL
+    }
+    
+    ruleProc <- function (ruletypelist){
+        for (rule in ruletypelist){
+            #TODO check to see if they've already been calculated
+            
+            if(!is.function(get(rule$name))){
+                if(!is.function(get(paste("sig",rule$name,sep='.')))){
+                    message(paste("Skipping rule",rule$name,"because there is no function by that name to call"))
+                    next()      
+                } else {
+                    rule$name<-paste("sig",rule$name,sep='.')
+                }
+            }
+            
+            if(!isTRUE(rule$enabled)) next()
+            
+            # see 'S Programming p. 67 for this matching
+            fun<-match.fun(rule$name)
+            
+            .formals  <- formals(fun)
+            onames <- names(.formals)
+            
+            pm <- pmatch(names(rule$arguments), onames, nomatch = 0L)
+            if (any(pm == 0L))
+                warning(paste("some arguments stored for",rule$name,"do not match"))
+            names(rule$arguments[pm > 0L]) <- onames[pm]
+            .formals[pm] <- rule$arguments[pm > 0L]
+            #now add dots
+            if (length(nargs)) {
+                pm <- pmatch(names(nargs), onames, nomatch = 0L)
+                names(nargs[pm > 0L]) <- onames[pm]
+                .formals[pm] <- nargs[pm > 0L]
+            }
+            .formals$... <- NULL
+            
+            tmp_val<-do.call(fun,.formals)
+            if(is.null(names(tmp_val)) & ncol(tmp_val)==1) names(tmp_val)<-rule$label
+            if (nrow(mktdata)==nrow(tmp_val) | length(mktdata)==length(tmp_val)) {
+                # the rule returned a time series, so we'll name it and cbind it
+                mktdata<-cbind(mktdata,tmp_val)
+            } else {
+                # the rule returned something else, add it to the ret list
+                if(is.null(ret)) ret<-list()
+                ret[[rule$name]]<-tmp_val
+            }
+            #print(tmp_val)
+        } #end rules loop
+        mktdata <<- mktdata
+        ret <<- ret
+        hold <<- hold
+    } # end sub process function
+    
+    hold=FALSE
+    for ( type in names(strategy$rules)){
+        switch( names(strategy$rules),
+                risk = {
+                    
+                },
+                order = {
+                    
+                }
+        
+        ) # send switch
+        
+    }
+    
+    if(is.null(ret)) return(mktdata)
+    else return(ret)
+}
+
+
+###############################################################################
+# R (http://r-project.org/) Quantitative Strategy Model Framework
+#
+# Copyright (c) 2009-2010
+# Peter Carl, Dirk Eddelbuettel, Brian G. Peterson, Jeffrey Ryan, and Joshua Ulrich 
+#
+# This library is distributed under the terms of the GNU Public License (GPL)
+# for full details see the file COPYING
+#
+# $Id$
+#
+###############################################################################

Modified: pkg/quantstrat/R/signals.R
===================================================================
--- pkg/quantstrat/R/signals.R	2010-02-06 12:11:21 UTC (rev 231)
+++ pkg/quantstrat/R/signals.R	2010-02-06 14:13:22 UTC (rev 232)
@@ -30,7 +30,7 @@
 #' apply the signals in the strategy to arbitrary market data
 #' @param strategy an object of type 'strategy' to add the signal to
 #' @param mktdata an xts object containing market data.  depending on signals, may need to be in OHLCV or BBO formats
-#' @param indicators if indicator output is not contained in the mktdata object, it may be passed separately an xts object or a list.
+#' @param indicators if indicator output is not contained in the mktdata object, it may be passed separately as an xts object or a list.
 #' @param ... any other passthru parameters
 #' @export
 applySignals <- function(strategy, mktdata, indicators=NULL, ...) {
@@ -39,6 +39,8 @@
     # TODO check for symbol name in mktdata using Josh's code:
     # symbol <- strsplit(colnames(mktdata)[1],"\\.")[[1]][1]
     
+    # TODO handle indicator lists as well as indicators that were cbound to mktdata
+    
     if (!is.strategy(strategy)) {
         strategy<-try(getStrategy(strategy))
         if(inherits(strategy,"try-error"))
@@ -98,7 +100,7 @@
         #print(tmp_val)
     } #end signals loop
     if(is.null(ret)) return(mktdata)
-    else return(list(mktdata=mktdata,signal_ret=ret))
+    else return(ret)
 }
 
 
@@ -174,7 +176,7 @@
 #' @export
 sigPeak <- function(label,data,column, direction=c("peak","bottom")){
     #should we only do this for one column?
-    column<-match.names(colnames(data),columns)
+    column<-match.names(colnames(data),column)
     direction=direction[1] # only use the first]
     #(Lag(IBM[,4],2)<Lag(IBM[,4],1)) & Lag(IBM[,4],1) >IBM[,4]
     switch(direction,
@@ -206,13 +208,13 @@
             'gt' = {ret_sig = data[,column] > threshold},
             '<' =,
             'lt' = {ret_sig = data[,column] < threshold},
-            'eq'     = {ret_sig = data[,columns[1]] == threshold}, #FIXME any way to specify '='?
+            'eq'     = {ret_sig = data[,column] == threshold}, #FIXME any way to specify '='?
             'gte' =,
             'gteq'=,
-            'ge'     = {ret_sig = data[,columns[1]] >= threshold}, #FIXME these fail with an 'unexpected =' error if you use '>='
+            'ge'     = {ret_sig = data[,column] >= threshold}, #FIXME these fail with an 'unexpected =' error if you use '>='
             'lte' =,
             'lteq'=,
-            'le'     = {ret_sig = data[,columns[1]] <= threshold}
+            'le'     = {ret_sig = data[,column] <= threshold}
     )
     colnames(ret_sig)<-label
     return(ret_sig)

Added: pkg/quantstrat/man/applyRules.Rd
===================================================================
--- pkg/quantstrat/man/applyRules.Rd	                        (rev 0)
+++ pkg/quantstrat/man/applyRules.Rd	2010-02-06 14:13:22 UTC (rev 232)
@@ -0,0 +1,13 @@
+\name{applyRules}
+\alias{applyRules}
+\title{apply the rules in the strategy to arbitrary market data...}
+\usage{applyRules(strategy, mktdata, indicators, signals, ..., path.dep=TRUE)}
+\description{apply the rules in the strategy to arbitrary market data}
+\details{In typical usage, this function will be called via \code{\link{applyStrategy}}.  In this mode, this function will be called twice, once with \code{path.dep=FALSE} and then again in stepping over the .}
+\seealso{\code{\link{add.rule}} \code{\link{applyStrategy}}}
+\arguments{\item{strategy}{an object of type 'strategy' to add the rule to}
+\item{mktdata}{an xts object containing market data.  depending on rules, may need to be in OHLCV or BBO formats, and may include indicator and signal information}
+\item{indicators}{if indicator output is not contained in the mktdata object, it may be passed separately as an xts object or a list.}
+\item{signals}{if signal output is not contained in the mktdata object, it may be passed separately as an xts object or a list.}
+\item{...}{any other passthru parameters}
+\item{path.dep}{TRUE/FALSE whether rule is path dependent, default TRUE, see Details}}


Property changes on: pkg/quantstrat/man/applyRules.Rd
___________________________________________________________________
Name: svn:keywords
   + Revision Id Date Author

Modified: pkg/quantstrat/man/applySignals.Rd
===================================================================
--- pkg/quantstrat/man/applySignals.Rd	2010-02-06 12:11:21 UTC (rev 231)
+++ pkg/quantstrat/man/applySignals.Rd	2010-02-06 14:13:22 UTC (rev 232)
@@ -5,5 +5,5 @@
 \description{apply the signals in the strategy to arbitrary market data}
 \arguments{\item{strategy}{an object of type 'strategy' to add the signal to}
 \item{mktdata}{an xts object containing market data.  depending on signals, may need to be in OHLCV or BBO formats}
-\item{indicators}{if indicator output is not contained in the mktdata object, it may be passed separately an xts object or a list.}
+\item{indicators}{if indicator output is not contained in the mktdata object, it may be passed separately as an xts object or a list.}
 \item{...}{any other passthru parameters}}



More information about the Blotter-commits mailing list