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

noreply at r-forge.r-project.org noreply at r-forge.r-project.org
Thu Oct 28 18:41:13 CEST 2010


Author: braverock
Date: 2010-10-28 18:41:12 +0200 (Thu, 28 Oct 2010)
New Revision: 434

Modified:
   pkg/quantstrat/R/orders.R
   pkg/quantstrat/R/rules.R
   pkg/quantstrat/R/strategy.R
   pkg/quantstrat/man/add.rule.Rd
   pkg/quantstrat/man/addOrder.Rd
   pkg/quantstrat/man/getOrders.Rd
   pkg/quantstrat/man/ruleSignal.Rd
Log:
- apply dimension reduction to path dependent rules with signature like ruleSignal
- skip indices where we don't need to do anything, process every index while we have open orders
- update docs

Modified: pkg/quantstrat/R/orders.R
===================================================================
--- pkg/quantstrat/R/orders.R	2010-10-28 13:19:39 UTC (rev 433)
+++ pkg/quantstrat/R/orders.R	2010-10-28 16:41:12 UTC (rev 434)
@@ -64,7 +64,7 @@
 #' @param portfolio text name of the portfolio to associate the order book with
 #' @param symbol identfier of the instrument to find orders for.  The name of any associated price objects (xts prices, usually OHLC) should match these
 #' @param status one of "open", "closed", "canceled", or "replaced", default "open"
-#' @param timespan xts-style character timespan to be the period to find orders of the given status and ordertype 
+#' @param timespan xts-style character timespan to be the period to find orders of the given status and ordertype, not yet used here
 #' @param ordertype one of NULL, "market","limit","stoplimit", "stoptrailing", or "iceberg" default NULL
 #' @param side one of NULL, "long" or "short", default NULL 
 #' @param which.i if TRUE, return the row index numbers rather than the order rows matching the criteria, default FALSE

Modified: pkg/quantstrat/R/rules.R
===================================================================
--- pkg/quantstrat/R/rules.R	2010-10-28 13:19:39 UTC (rev 433)
+++ pkg/quantstrat/R/rules.R	2010-10-28 16:41:12 UTC (rev 434)
@@ -47,6 +47,14 @@
 #' 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.
+#' 
+#' For quantstrat to be able to (largly) vectorize the execution of path-dependent 
+#' rule evaluation, the rule function is presumed to have a function signature 
+#' like that of \code{\link{ruleSignal}}, specifically the arguments \code{sigcol} 
+#' and \code{sigval}.  If these are present and function in a way similar to 
+#' \code{\link{ruleSignal}} we can do some preprocessing to significantly reduce the 
+#' dimensionality of the index we need to loop over.  The speedup is the ratio of 
+#' (symbols*total observations)/signal observations, so it can be significant for many strategies.
 #'    
 #' @param strategy an object of type 'strategy' to add the rule to
 #' @param name name of the rule, must correspond to an R function
@@ -214,25 +222,71 @@
             ## }
             mktdata <<- mktdata
             ret <<- ret
-            hold <<- hold #TODO FIXME hold processing doesn't work yet
+            hold <<- hold #TODO FIXME hold processing doesn't work unless custom rule has set it with <<-
 
             #print(tmp_val)
         } #end rules loop
     } # end sub process function
 
-    #TODO FIXME we should probably do something more sophisticated, but this should work
-    if(isTRUE(path.dep) & is.null(Dates)) Dates=unique(time(mktdata)) # should this be index() instead?
-    if(!isTRUE(path.dep)) Dates=''
+    #we could maybe do something more sophisticated, but this should work
+    if(isTRUE(path.dep)){
+        Dates=unique(time(mktdata)) # should this be index() instead?  
+    } else {
+        Dates=''
+    }
+    
 
     hold=FALSE
     holdtill=first(time(Dates))-1 # TODO FIXME make holdtill default more robust?
 
 	mktinstr<-getInstrument(symbol)
 	
-    for(d in 1:length(Dates)){ # d is a date slot counter
+    dindex<-vector()
+    #pre-process for dimension reduction here
+    for ( type in names(strategy$rules)){
+        # check if there's anything to do
+        if(length(strategy$rules[[type]])>=1){
+            for (rule in strategy$rules[[type]]){
+                if(isTRUE(rule$path.dep)){ # only apply to path dependent rule
+                    # check for sigcol, sigval, otherwise use all
+                    if(is.null(rule$arguments$sigcol) | is.null(rule$arguments$sigval) ){
+                        dindex<-1:length(Dates)
+                    } else {
+                        dindex<-c(dindex,which(mktdata[,rule$arguments$sigcol] == rule$arguments$sigval))   
+                    }
+                }
+            }
+        }    
+    }
+    dindex<-sort(unique(dindex))
+    if(length(dindex)==0) dindex=1
+    
+    # TODO change this to a while?
+    curIndex<-1
+
+    nextIndex<-function(curIndex,...){
+        if (!isTRUE(path.dep)){
+            curIndex = FALSE
+            return(curIndex)
+        } 
+        
+        #check for open orders at curIndex
+        rem.orders <- getOrders(portfolio=portfolio, symbol=symbol, status="open") #, timespan=timespan, ordertype=ordertype,which.i=TRUE)
+        if(nrow(rem.orders)==0){
+            curIndex<-dindex[first(which(dindex>curIndex))]
+            if(is.na(curIndex)) curIndex=FALSE
+        } else { # open orders, set to curIndex+1
+            curIndex<-curIndex+1
+        }
+        if (curIndex > length(Dates)) curIndex=FALSE
+        return(curIndex)
+    }
+        
+    while(curIndex){
+    #for(d in 1:length(Dates)){ # d is a date slot counter
         # I shouldn't have to do this but we lose the class for the element 
         # when we do for(date in Dates)
-        timestamp=Dates[d]    
+        timestamp=Dates[curIndex]    
 
         # check to see if we need to release a hold
         if(isTRUE(hold) & holdtill<timestamp){
@@ -272,13 +326,15 @@
                         }
                     },
                     post = {
-                        #TODO do we processfor hold here, or not?
+                        #TODO do we process for hold here, or not?
                         if(length(strategy$rules$post)>=1) {
                             ruleProc(strategy$rules$post,timestamp=timestamp, path.dep=path.dep, mktdata=mktdata,portfolio=portfolio, symbol=symbol, ruletype=type, mktinstr=mktinstr, ...)
                         }
                     }
             ) # end switch
         } #end type loop
+        curIndex<-nextIndex(curIndex, ...)
+        if(!isTRUE(path.dep)) curIndex=FALSE
     } # end dates loop
 
     mktdata<<-mktdata

Modified: pkg/quantstrat/R/strategy.R
===================================================================
--- pkg/quantstrat/R/strategy.R	2010-10-28 13:19:39 UTC (rev 433)
+++ pkg/quantstrat/R/strategy.R	2010-10-28 16:41:12 UTC (rev 434)
@@ -36,12 +36,7 @@
         # if assets is a named vector, we'll assume it is current weights
     }
     rules<-list()
-    rules$risk<-list()
     rules$order<-list()
-    rules$rebalance<-list()
-    rules$exit<-list()
-    rules$enter<-list()
-    
     ## now structure and return
     strat<-structure(
                     list(

Modified: pkg/quantstrat/man/add.rule.Rd
===================================================================
--- pkg/quantstrat/man/add.rule.Rd	2010-10-28 13:19:39 UTC (rev 433)
+++ pkg/quantstrat/man/add.rule.Rd	2010-10-28 16:41:12 UTC (rev 434)
@@ -51,7 +51,15 @@
 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.}
+authors a place to start.
+
+For quantstrat to be able to (largly) vectorize the execution of path-dependent 
+rule evaluation, the rule function is presumed to have a function signature 
+like that of \code{\link{ruleSignal}}, specifically the arguments \code{sigcol} 
+and \code{sigval}.  If these are present and function in a way similar to 
+\code{\link{ruleSignal}} we can do some preprocessing to significantly reduce the 
+dimensionality of the index we need to loop over.  The speedup is the ratio of 
+(symbols*total observations)/signal observations, so it can be significant for many strategies.}
 \arguments{\item{strategy}{an object of type 'strategy' to add the rule to}
 \item{name}{name of the rule, must correspond to an R function}
 \item{arguments}{named list of default arguments to be passed to an rule function when executed}

Modified: pkg/quantstrat/man/addOrder.Rd
===================================================================
--- pkg/quantstrat/man/addOrder.Rd	2010-10-28 13:19:39 UTC (rev 433)
+++ pkg/quantstrat/man/addOrder.Rd	2010-10-28 16:41:12 UTC (rev 434)
@@ -13,7 +13,7 @@
 (the Rules) and then enter orders (the province of this function in backtesting),
 during which there is some \code{delay} between receiving the data that fires the 
 Signal and Rule, and the time the order reaches the market, and then those orders 
-MAY become transactions if market prices and liquidity cooperate.  
+\emph{MAY} become transactions if market prices and liquidity cooperate.  
 
 By default, this function will locate and replace any 'open' order(s) 
 on the requested portfolio/symbol that have the same type and side.  
@@ -52,7 +52,7 @@
 
 We have also added the 'iceberg' order type.  This order type should
 most often be paired with \code{delay} and \code{\link{osMaxPos}}.  The 
-iceberg order will enter when initially entered is treated like a limit 
+iceberg order when initially entered is treated like a limit 
 order, with an optional threshold (which is applied at initial order 
 entry, so be careful).  Right now, they will enter a new order at price+threshold
 upon any execution of the prior iceberg order.  This process could 

Modified: pkg/quantstrat/man/getOrders.Rd
===================================================================
--- pkg/quantstrat/man/getOrders.Rd	2010-10-28 13:19:39 UTC (rev 433)
+++ pkg/quantstrat/man/getOrders.Rd	2010-10-28 16:41:12 UTC (rev 434)
@@ -12,7 +12,7 @@
 \arguments{\item{portfolio}{text name of the portfolio to associate the order book with}
 \item{symbol}{identfier of the instrument to find orders for.  The name of any associated price objects (xts prices, usually OHLC) should match these}
 \item{status}{one of "open", "closed", "canceled", or "replaced", default "open"}
-\item{timespan}{xts-style character timespan to be the period to find orders of the given status and ordertype}
+\item{timespan}{xts-style character timespan to be the period to find orders of the given status and ordertype, not yet used here}
 \item{ordertype}{one of NULL, "market","limit","stoplimit", "stoptrailing", or "iceberg" default NULL}
 \item{side}{one of NULL, "long" or "short", default NULL}
 \item{which.i}{if TRUE, return the row index numbers rather than the order rows matching the criteria, default FALSE}}

Modified: pkg/quantstrat/man/ruleSignal.Rd
===================================================================
--- pkg/quantstrat/man/ruleSignal.Rd	2010-10-28 13:19:39 UTC (rev 433)
+++ pkg/quantstrat/man/ruleSignal.Rd	2010-10-28 16:41:12 UTC (rev 434)
@@ -4,7 +4,7 @@
 \usage{ruleSignal(data=mktdata, timestamp, sigcol, sigval, orderqty=0,
     ordertype, orderside, threshold, tmult=FALSE, replace=TRUE,
     delay=1e-04, osFUN="osNoOp", pricemethod=c("market", "opside",
-    "maker"), portfolio, symbol, ..., ruletype, TxnFees=0)}
+    "maker"), portfolio, symbol, ..., ruletype, TxnFees=0, prefer)}
 \description{default rule to generate a trade order on a signal}
 \details{\code{pricemethod} may be one of 'market', 'opside', or 'maker' 
 which will either try to get the price of the 'market' at \code{timestamp} and use this as the order price
@@ -37,4 +37,5 @@
 \item{symbol}{identifier of the instrument to place orders for.  The name of any associated price objects (xts prices, usually OHLC) should match these}
 \item{...}{any other passthru parameters}
 \item{ruletype}{one of "risk","order","rebalance","exit","entry", see \code{\link{add.rule}}}
-\item{TxnFees}{numeric fees (usually negative) or function name for calculating TxnFees (processing happens later, not in this function)}}
+\item{TxnFees}{numeric fees (usually negative) or function name for calculating TxnFees (processing happens later, not in this function)}
+\item{prefer}{price method for getPrice}}



More information about the Blotter-commits mailing list