[Blotter-commits] r251 - pkg/quantstrat/R

noreply at r-forge.r-project.org noreply at r-forge.r-project.org
Tue Feb 23 21:23:09 CET 2010


Author: braverock
Date: 2010-02-23 21:23:09 +0100 (Tue, 23 Feb 2010)
New Revision: 251

Modified:
   pkg/quantstrat/R/traderules.R
Log:
- add orderside detection if NULL 

Modified: pkg/quantstrat/R/traderules.R
===================================================================
--- pkg/quantstrat/R/traderules.R	2010-02-23 15:20:48 UTC (rev 250)
+++ pkg/quantstrat/R/traderules.R	2010-02-23 20:23:09 UTC (rev 251)
@@ -1,15 +1,24 @@
 
-#' default rule to execute a trade on a signal
+#' default rule to generate a trade order on a signal
 #' 
-#' \code{pricemethod} may be one of 'market' and 'opside' which will either try to get the price of the market at \code{timestamp} and use this as the order price
+#' \code{pricemethod} may be one of 'market' or 'opside' 
+#' which will either try to get the price of the 'market' at \code{timestamp} and use this as the order price
+#' or 'opside' which will use the 'ask' price if you're buying and the 'bid' price if you're selling
+#' 
+#' If \code{threshold} is not numeric or \code{NULL} it should be the character string describing a function that can calculate a threshold.  
+#' Ideally this will be a column lookup on a non-path-dependent indicator calculated in advance.
+#' 
+#' If \code{orderside} is NULL, the function will attempt to calculate the side from the current position 
+#' (if any) and the order quantity.    
+#'   
 #' @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 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, modified by osFUN
 #' @param ordertype one of "market","limit","stoplimit", or "stoptrailing"
-#' @param orderside one of either "long" or "short" 
-#' @param threshold numeric threshold to apply to trailing stop orders, default NULL
+#' @param orderside one of either "long" or "short", default NULL, see details 
+#' @param threshold numeric or function threshold to apply to trailing stop orders, default NULL, see Details
 #' @param replace TRUE/FALSE, whether to replace any other open order(s) on this portfolio symbol, default TRUE 
 #' @param delay what delay to add to timestamp when inserting the order into the order book, in seconds
 #' @param osFUN function or text descriptor of function to use for order sizing, default \code{\link{osNoOp}}
@@ -19,19 +28,44 @@
 #' @param ... any other passthru parameters
 #' @seealso \code{\link{osNoOp}}
 #' @export
-ruleSignal <- function(mktdata, timestamp, sigcol, sigval, orderqty=0, ordertype, orderside, threshold, replace=TRUE, delay=0.0001, osFUN='osNoOp', pricemethod=c('market','opside'), portfolio, symbol, ... ) {
+ruleSignal <- function(mktdata, timestamp, sigcol, sigval, orderqty=0, ordertype, orderside, threshold=NULL, replace=TRUE, delay=0.0001, osFUN='osNoOp', pricemethod=c('market','opside'), portfolio, symbol, ... ) {
     if(!is.function(osFUN)) osFUN<-match.fun(osFUN)
     if (mktdata[timestamp][,sigcol] == sigval) {
         #TODO add fancy formals matching for osFUN
         orderqty <- osFUN(strategy, mktdata, timestamp, orderqty, ordertype, orderside, portfolio, symbol)
-        #TODO calculate order price using pricemethod
+        #calculate order price using pricemethod
         switch(pricemethod,
-               opside = {}, #getPrice...
-               market = {}  #getPrice...
+               opside = {
+                   if (orderqty>0) 
+                       prefer='ask'  # we're buying, so pay what they're asking
+                   else
+                       prefer='bid'  # we're selling, so give it to them for what they're bidding
+                   orderprice <- try(getPrice(x=mktdata,symbol=symbol,prefer=prefer))
+               }, 
+               market = { 
+                   orderprice <- try(getPrice(x=mktdata,symbol=symbol,prefer=NULL)) 
+               }  
         )
-        if(!is.null(orderqty) & !orderqty == 0){
-            addOrder(portfolio, symbol, timestamp, orderqty, orderprice, ordertype=ordertype, side=orderside, status="open", replace=replace , delay=delay, ...)
+        if(inherits(orderprice,'try-error')) orderprice<-NULL
+        if(is.NULL(orderside) & !orderqty == 0){
+            curqty<-getPosQty(Portfolio=portfolio, Symbol=symbol, Date=timestamp)
+            if (curqty>0 ){
+                #we have a long position
+                orderside<-'long'
+            } else if (curqty<0){
+                #we have a short position
+                orderside<-'short'
+            } else {
+                # no current position, which way are we going?
+                if (orderqty>0) 
+                    orderside<-'long'
+                else
+                    orderside<-'short'
+            }
         }
+        if(!is.null(orderqty) & !orderqty == 0 & !is.null(orderprice)){
+            addOrder(portfolio, symbol, timestamp, orderqty, orderprice, ordertype=ordertype, side=orderside, threshold=threshold, status="open", replace=replace , delay=delay, ...)
+        }
     }
 }
 
@@ -58,6 +92,12 @@
 
 #' add position and level limits at timestamp
 #' 
+#' levels are a simplification of more complex (proprietary) 
+#' techniques sometimes used for order sizing.  
+#' the max orderqty returned will be the limit/levels
+#' Obviously the strategy rules could ask for smaller order sizes, 
+#' but this is the default.  If you don't want to use levels, set 
+#' them to 1.
 #' @param portfolio text name of the portfolio to place orders in
 #' @param symbol identifier of the instrument to place 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 the order will be inserted on 
@@ -91,6 +131,7 @@
 #' @param portfolio text name of the portfolio to place orders in
 #' @param symbol identifier of the instrument to place 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 the order will be inserted on 
+#' @seealso \code{\link{addPosLimit}},\code{\link{osMaxPos}}
 getPosLimit <- function(portfolio, symbol, timestamp){
     portf<-getPortfolio(portfolio)
     # try to get on timestamp, otherwise find the most recent
@@ -115,6 +156,7 @@
 #' @param orderside one of either "long" or "short" 
 #' @param portfolio text name of the portfolio to place orders in
 #' @param symbol identifier of the instrument to place orders for.  The name of any associated price objects (xts prices, usually OHLC) should match these
+#' @seealso \code{\link{addPosLimit}},\code{\link{getPosLimit}}
 #' @export
 osMaxPos <- function(mktdata, timestamp, orderqty, ordertype, orderside, portfolio, symbol){
     # check for current position



More information about the Blotter-commits mailing list