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

noreply at r-forge.r-project.org noreply at r-forge.r-project.org
Sun Nov 4 15:50:22 CET 2012


Author: opentrades
Date: 2012-11-04 15:50:22 +0100 (Sun, 04 Nov 2012)
New Revision: 1238

Modified:
   pkg/quantstrat/DESCRIPTION
   pkg/quantstrat/NAMESPACE
   pkg/quantstrat/R/orders.R
   pkg/quantstrat/R/osFUNs.R
   pkg/quantstrat/R/ruleOrderProc.R
   pkg/quantstrat/R/ruleSignal.R
   pkg/quantstrat/R/rules.R
   pkg/quantstrat/man/addOrder.Rd
   pkg/quantstrat/man/ruleSignal.Rd
Log:
support for orderqty='trigger' to kick in new orderchain



Modified: pkg/quantstrat/DESCRIPTION
===================================================================
--- pkg/quantstrat/DESCRIPTION	2012-11-03 16:47:18 UTC (rev 1237)
+++ pkg/quantstrat/DESCRIPTION	2012-11-04 14:50:22 UTC (rev 1238)
@@ -16,3 +16,21 @@
 Contributors: Yu Chen, Joe Dunn, Jan Humme
 LazyLoad: yes
 License: GPL-3
+Collate:
+    'applyStrategy.rebalancing.R'
+    'indicators.R'
+    'initialize.R'
+    'match.names.R'
+    'orders.R'
+    'osFUNs.R'
+    'parameters.R'
+    'paramsets.R'
+    'ruleCancel.R'
+    'ruleOrderProc.R'
+    'rules.R'
+    'ruleSignal.R'
+    'signals.R'
+    'strategy.R'
+    'tradeGraphs.R'
+    'utils.R'
+    'wrapup.R'

Modified: pkg/quantstrat/NAMESPACE
===================================================================
--- pkg/quantstrat/NAMESPACE	2012-11-03 16:47:18 UTC (rev 1237)
+++ pkg/quantstrat/NAMESPACE	2012-11-04 14:50:22 UTC (rev 1238)
@@ -11,8 +11,8 @@
 export(applyParameter)
 export(applyRules)
 export(applySignals)
+export(applyStrategy.rebalancing)
 export(applyStrategy)
-export(applyStrategy.rebalancing)
 export(delete.paramset)
 export(getOrderBook)
 export(getOrders)

Modified: pkg/quantstrat/R/orders.R
===================================================================
--- pkg/quantstrat/R/orders.R	2012-11-03 16:47:18 UTC (rev 1237)
+++ pkg/quantstrat/R/orders.R	2012-11-04 14:50:22 UTC (rev 1238)
@@ -194,7 +194,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 timestamp timestamp coercible to POSIXct that will be the time to search for orders before this time 
-#' @param qty numeric quantity of the order
+#' @param qty numeric quantity of the order, or "all" or "trigger"
 #' @param price numeric price at which the order is to be inserted
 #' @param ordertype one of "market","limit","stoplimit", "stoptrailing" or "iceberg"
 #' @param side one of either "long" or "short" 
@@ -239,8 +239,8 @@
     #if(!length(grep(symbol,names(orderbook[[portfolio]])))==1) stop(paste("symbol",symbol,"does not exist in portfolio",portfolio,"having symbols",names(orderbook[[portfolio]])))
 
     #data quality checks
-    if(!is.numeric(qty) && !(qty=='all')) stop (paste("Quantity must be numeric:",qty))
-    if(qty==0) stop("qty",qty,"must positive, negative, or 'all'")
+    if(!is.numeric(qty) && !(qty=='all') && !(qty=='trigger')) stop (paste("Quantity must be numeric:",qty))
+    if(qty==0) stop("qty",qty,"must positive, negative, or 'all' or 'trigger'")
     if(is.null(qty)) stop("qty",qty,"must not be NULL")
     if(is.na(qty)) stop("qty",qty,"must not be NA")
     if(!is.numeric(price)) stop (paste("Price must be numeric:",price))
@@ -270,7 +270,7 @@
                     {
                         switch(ordertype,
                             limit = {
-                                if(qty == 'all' && side == 'long' || qty != 'all' && as.numeric(qty) < 0) # SELL
+                                if((qty %in% c('all','trigger')) && side == 'long' || !(qty %in% c('all','trigger')) && as.numeric(qty) < 0) # SELL
                                 {
                                     #this is a limit exit, so it will sell *higher* than the current market
                                     if(threshold < 0) threshold = -threshold
@@ -283,7 +283,7 @@
                             },
                             stoplimit =,
                             stoptrailing = {
-                                if(qty == 'all' && side == 'long' || qty != 'all' && as.numeric(qty) < 0) # SELL
+                                if((qty %in% c('all','trigger')) && side == 'long' || !(qty %in% c('all','trigger')) && as.numeric(qty) < 0) # SELL
                                 {
                                     #this is a stop exit, so it will sell *lower* than the current market
                                     if(threshold > 0) threshold = -threshold

Modified: pkg/quantstrat/R/osFUNs.R
===================================================================
--- pkg/quantstrat/R/osFUNs.R	2012-11-03 16:47:18 UTC (rev 1237)
+++ pkg/quantstrat/R/osFUNs.R	2012-11-04 14:50:22 UTC (rev 1238)
@@ -12,16 +12,17 @@
 #' @param ... any other passthru parameters
 #' @param ruletype one of "risk","order","rebalance","exit","enter", see \code{\link{add.rule}}
 #' @export
-osNoOp <- function(timestamp, orderqty, portfolio, symbol, ruletype, ...){
-    # handle orderqty=='all' for ruletype!= 'exit' or 'risk'
-    if(orderqty=='all' && !(ruletype=='exit' || ruletype=='risk')) {
-        stop(paste("orderqty 'all' would produce nonsense, maybe use osMaxPos instead?\n",
+osNoOp <- function(timestamp, orderqty, portfolio, symbol, ruletype, ...)
+{
+    if(orderqty == 'all' && !(ruletype %in% c('exit','risk'))
+    || orderqty == 'trigger' && ruletype != 'chain')
+    {
+        stop(paste("orderqty 'all'/'trigger' would produce nonsense, maybe use osMaxPos instead?\n",
                    "Order Details:\n",
                    'Timestamp:',timestamp,
                    'Qty:',orderqty,
                    'Symbol:',symbol)
         )
-        orderqty=0 # in case we go back to returning this so that we reject it in the orderbook
     }
 	return(orderqty)
 }

Modified: pkg/quantstrat/R/ruleOrderProc.R
===================================================================
--- pkg/quantstrat/R/ruleOrderProc.R	2012-11-03 16:47:18 UTC (rev 1237)
+++ pkg/quantstrat/R/ruleOrderProc.R	2012-11-04 14:50:22 UTC (rev 1238)
@@ -87,7 +87,7 @@
             orderPrice <- as.numeric(ordersubset[ii,"Order.Price"])
 
             orderQty <- ordersubset[ii,"Order.Qty"]
-            if(orderQty=='all')
+            if(orderQty %in% c('all','trigger'))
             {
                 # this has to be an exit or risk order, so: 
                 orderQty=-1*getPosQty(Portfolio=portfolio,Symbol=symbol,Date=timestamp)
@@ -352,8 +352,11 @@
                 }
                 else    #add the transaction
                 {
-                    addTxn(Portfolio=portfolio, Symbol=symbol, TxnDate=txntime, 
-                            TxnQty=orderQty, TxnPrice=txnprice , ...=..., TxnFees=txnfees)
+                    if(ordersubset[ii,"Order.Qty"] != 'trigger')
+                    {
+                        addTxn(Portfolio=portfolio, Symbol=symbol, TxnDate=txntime, 
+                                TxnQty=orderQty, TxnPrice=txnprice , ...=..., TxnFees=txnfees)
+                    }
                     ordersubset[ii,"Order.Status"]<-'closed'
                 }
                 ordersubset[ii,"Order.StatusTime"]<-format(timestamp, "%Y-%m-%d %H:%M:%S")

Modified: pkg/quantstrat/R/ruleSignal.R
===================================================================
--- pkg/quantstrat/R/ruleSignal.R	2012-11-03 16:47:18 UTC (rev 1237)
+++ pkg/quantstrat/R/ruleSignal.R	2012-11-04 14:50:22 UTC (rev 1238)
@@ -19,6 +19,8 @@
 #'            This will then create an Order.Set, and use the \code{threshold} to set the prices for these orders.}
 #'      } 
 #' 
+#' \code{orderqty} should be either numeric, or one of 'all'/'trigger'. 'all' can only be used with order of ruletype='exit' or 'risk', and will close the entire position. 'trigger' can only be used with ruletype='chain' and is exactly identical to 'all', except that the actual transaction is suppressed, and can be used to kick in a new order chain.
+#' 
 #' If \code{threshold} is not numeric or \code{NULL} it should be the name of an indicator mktdata column holding the threshold values.
 #' 
 #' If \code{orderside} is NULL, the function will attempt to calculate the side from the current position 
@@ -28,7 +30,7 @@
 #' @param timestamp timestamp coercible to POSIXct that will be the time the order will be inserted on 
 #' @param sigcol column name to check for signal
 #' @param sigval signal value to match against
-#' @param orderqty numeric quantity of the desired order, or 'all', modified by osFUN
+#' @param orderqty numeric quantity of the desired order, or one of 'all'/'trigger', modified by osFUN
 #' @param ordertype one of "market","limit","stoplimit", "stoptrailing", or "iceberg"
 #' @param orderside one of either "long" or "short", default NULL, see details 
 #' @param orderset tag to identify an orderset; if one order of the set is filled, all others are canceled

Modified: pkg/quantstrat/R/rules.R
===================================================================
--- pkg/quantstrat/R/rules.R	2012-11-03 16:47:18 UTC (rev 1237)
+++ pkg/quantstrat/R/rules.R	2012-11-04 14:50:22 UTC (rev 1238)
@@ -345,16 +345,16 @@
                 {
                     dindex <- get.dindex()
                     tmpqty <- ordersubset[oo.idx[slorder],'Order.Qty']
-                    if (tmpqty=='all'){
-                    #tmpqty<-osNoOp(timestamp=timestamp, orderqty=tmpqty, portfolio=portfolio, symbol=symbol,ruletype='exit' )
-                    #set to 0, and let the next block figure it out from orderside
-                    tmpqty=0
+                    if (tmpqty=='all' || tmpqty=='trigger'){
+                        #tmpqty<-osNoOp(timestamp=timestamp, orderqty=tmpqty, portfolio=portfolio, symbol=symbol,ruletype='exit' )
+                        #set to 0, and let the next block figure it out from orderside
+                        tmpqty=0
                     } 
                     if (tmpqty==0) {
-                    #no position, so do some sleight of hand to figure out when the index may be needed
-                    side <- ordersubset[oo.idx[slorder],'Order.Side']
-                    if(side=='long') tmpqty=-1
-                    else tmpqty=1
+                        #no position, so do some sleight of hand to figure out when the index may be needed
+                        side <- ordersubset[oo.idx[slorder],'Order.Side']
+                        if(side=='long') tmpqty=-1
+                        else tmpqty=1
                     }
                     tmpqty<-as.numeric(tmpqty)
                     tmpprice <- as.numeric(ordersubset[oo.idx[slorder],'Order.Price'])
@@ -394,16 +394,16 @@
                 {
                     dindex<-get.dindex()
                     tmpqty<-ordersubset[oo.idx[lorder],'Order.Qty']
-                    if (tmpqty=='all'){
-                    #tmpqty<-osNoOp(timestamp=timestamp, orderqty=tmpqty, portfolio=portfolio, symbol=symbol,ruletype='exit' )
-                    #set to 0, and let the next block figure it out from orderside
-                    tmpqty=0
+                    if (tmpqty=='all' || tmpqty=='trigger'){
+                        #tmpqty<-osNoOp(timestamp=timestamp, orderqty=tmpqty, portfolio=portfolio, symbol=symbol,ruletype='exit' )
+                        #set to 0, and let the next block figure it out from orderside
+                        tmpqty=0
                     } 
                     if (tmpqty==0) {
-                    #no position, so do some sleight of hand to figure out when the index may be needed
-                    side <- ordersubset[oo.idx[lorder],'Order.Side']
-                    if(side=='long') tmpqty=-1
-                    else tmpqty=1
+                        #no position, so do some sleight of hand to figure out when the index may be needed
+                        side <- ordersubset[oo.idx[lorder],'Order.Side']
+                        if(side=='long') tmpqty=-1
+                        else tmpqty=1
                     }
                     tmpqty<-as.numeric(tmpqty)
                     
@@ -460,7 +460,7 @@
                     onum<-oo.idx[torder]
                     orderThreshold <- as.numeric(ordersubset[onum,'Order.Threshold'])
                     tmpqty<-ordersubset[onum,'Order.Qty']
-                    if (tmpqty=='all'){
+                    if (tmpqty=='all' || tmpqty=='trigger'){
                         #tmpqty<-osNoOp(timestamp=timestamp, orderqty=tmpqty, portfolio=portfolio, symbol=symbol,ruletype='exit' )
                         #set to 0, and let the next block figure it out from orderside
                         tmpqty=0

Modified: pkg/quantstrat/man/addOrder.Rd
===================================================================
--- pkg/quantstrat/man/addOrder.Rd	2012-11-03 16:47:18 UTC (rev 1237)
+++ pkg/quantstrat/man/addOrder.Rd	2012-11-04 14:50:22 UTC (rev 1238)
@@ -19,7 +19,8 @@
   \item{timestamp}{timestamp coercible to POSIXct that will
   be the time to search for orders before this time}
 
-  \item{qty}{numeric quantity of the order}
+  \item{qty}{numeric quantity of the order, or "all" or
+  "trigger"}
 
   \item{price}{numeric price at which the order is to be
   inserted}

Modified: pkg/quantstrat/man/ruleSignal.Rd
===================================================================
--- pkg/quantstrat/man/ruleSignal.Rd	2012-11-03 16:47:18 UTC (rev 1237)
+++ pkg/quantstrat/man/ruleSignal.Rd	2012-11-04 14:50:22 UTC (rev 1238)
@@ -24,7 +24,7 @@
   \item{sigval}{signal value to match against}
 
   \item{orderqty}{numeric quantity of the desired order, or
-  'all', modified by osFUN}
+  one of 'all'/'trigger', modified by osFUN}
 
   \item{ordertype}{one of "market","limit","stoplimit",
   "stoptrailing", or "iceberg"}
@@ -103,6 +103,14 @@
   This will then create an Order.Set, and use the
   \code{threshold} to set the prices for these orders.} }
 
+  \code{orderqty} should be either numeric, or one of
+  'all'/'trigger'. 'all' can only be used with order of
+  ruletype='exit' or 'risk', and will close the entire
+  position. 'trigger' can only be used with
+  ruletype='chain' and is exactly identical to 'all',
+  except that the actual transaction is suppressed, and can
+  be used to kick in a new order chain.
+
   If \code{threshold} is not numeric or \code{NULL} it
   should be the name of an indicator mktdata column holding
   the threshold values.



More information about the Blotter-commits mailing list