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

noreply at r-forge.r-project.org noreply at r-forge.r-project.org
Fri Sep 16 17:07:53 CEST 2011


Author: gsee
Date: 2011-09-16 17:07:53 +0200 (Fri, 16 Sep 2011)
New Revision: 780

Modified:
   pkg/quantstrat/DESCRIPTION
   pkg/quantstrat/R/orders.R
   pkg/quantstrat/R/rules.R
   pkg/quantstrat/R/traderules.R
Log:
 - support for data that is neither OHLC nor BBO
 - allow order price to be zero. (think spreads)


Modified: pkg/quantstrat/DESCRIPTION
===================================================================
--- pkg/quantstrat/DESCRIPTION	2011-09-15 15:26:28 UTC (rev 779)
+++ pkg/quantstrat/DESCRIPTION	2011-09-16 15:07:53 UTC (rev 780)
@@ -1,7 +1,7 @@
 Package: quantstrat
 Type: Package
 Title: Quantitative Strategy Model Framework
-Version: 0.5.4
+Version: 0.5.5
 Date: $Date$
 Author: Peter Carl, Dirk Eddelbuettel, Brian G. Peterson,
     Jeffrey A. Ryan, Joshua Ulrich, Garrett See, Yu Chen

Modified: pkg/quantstrat/R/orders.R
===================================================================
--- pkg/quantstrat/R/orders.R	2011-09-15 15:26:28 UTC (rev 779)
+++ pkg/quantstrat/R/orders.R	2011-09-16 15:07:53 UTC (rev 780)
@@ -210,9 +210,9 @@
     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))
-    if(price==0) stop("price",price,"must be positive or negative")
-    if(is.null(price)) stop("price",price,"must not be NULL")
-    if(is.na(price)) stop("price",price,"must not be NA")
+    if(is.null(price)) stop("price ",price," must not be NULL")
+    if(is.na(price)) stop("order at timestamp ", timestamp, " must not have price of NA")
+    if(price==0) warning(paste(ordertype, "order for", qty, "has a price of zero."))
 
     if(!is.null(side) & !length(grep(side,c('long','short')))==1) stop(paste("side:",side," must be one of 'long' or 'short'"))
     if(is.na(charmatch(ordertype,c("market","limit","stoplimit","stoptrailing","iceberg")))) stop(paste("ordertype:",ordertype,' must be one of "market","limit","stoplimit","stoptrailing", or"iceberg"'))
@@ -415,10 +415,14 @@
     # get open orders
     procorders=NULL
     procorders<-getOrders(portfolio=portfolio, symbol=symbol, status="open", timespan=timespan, ordertype=ordertype, which.i=TRUE)
+
+    if(hasArg(prefer)) prefer=match.call(expand.dots=TRUE)$prefer
+    else prefer = NULL
+
     # check for open orders
     if (length(procorders)>=1){
         # get previous bar
-        prevtime  <- time(mktdata[last(mktdata[timespan, which.i = TRUE])-1]) #not used
+        prevtime  <- time(mktdata[last(mktdata[timespan, which.i = TRUE])-1]) 
         timestamp <- time(last(mktdata[timespan]))
         #switch on frequency
         freq = periodicity(mktdata)
@@ -449,7 +453,7 @@
                                 daily = {
                                     txntime=as.character(index(ordersubset[ii,])) # transacts on this bar, e.g. in the intraday cross, or leading into the end of month, quarter, etc.
                                     # txntime=as.character(timestamp) # use this if you wanted to transact on the close of the next bar
-                                    txnprice=as.numeric(getPrice(last(mktdata[txntime]), ...=...)[,1])
+                                    txnprice=as.numeric(getPrice(last(mktdata[txntime]), prefer=prefer)[,1])
                                 }, #end daily
                                 { 
                                     txntime = timestamp
@@ -464,27 +468,34 @@
                                             txnprice = min(orderPrice, as.numeric(getPrice(mktdataTimestamp,prefer='bid')[,1])) #presumes unique timestamp
                                         }
                                         #e.g. if pricemethod was opside, it sent a buy order at mktAsk. fill at greater of that ask, and current ask
-                                    } else txnprice = as.numeric(getPrice(mktdataTimestamp)[,1]) #filled at 'price'                                
+                                    } else txnprice = as.numeric(getPrice(mktdataTimestamp, prefer=prefer)[,1]) #filled at 'price'
                                 }) # end switch on frequency
                     },
                     limit= ,
                     stoplimit =,
                     iceberg = {
-                        if (isOHLCmktdata){
+                        if (!isBBOmktdata) { #(isOHLCmktdata){
                             if( orderType == 'iceberg'){
-                                stop("iceberg orders not supported for OHLC data")
+                                stop("iceberg orders only supported for BBO data")
                             } 
                             # check to see if price moved through the limit
-                            # FIXME: should this be the same for buys and sells?
-                            if( orderPrice > as.numeric(Lo(mktdataTimestamp)) & #what about an offer entered below the Lo?
-                                orderPrice < as.numeric(Hi(mktdataTimestamp)) ) #what about a bid entered above the Hi? 
-                                #should be: if buy order price > Lo || sell order price < Hi
-                            {
-                                txnprice = orderPrice
-                                txntime = timestamp
+                            if (orderQty > 0) { # positive quantity 'buy'
+                                if( (has.Lo(mktdata) && orderprice > as.numeric(Lo(mktdataTimestamp))) || 
+                                    (!has.Lo(mktdata) && orderprice >= as.numeric(getPrice(mktdataTimestamp, prefer=prefer))))
+                                {
+                                    txnprice = orderPrice
+                                    txntime = timestamp
+                                } else next() # price did not move through my order, should go to next order  
+                            } else if(orderQty < 0) { #negative quantity 'sell'
+                                if ( (has.Hi(mktdata) && orderprice < as.numeric(Hi(mktdataTimestamp))) ||
+                                     (!has.Hi(mktdata) && orderprice <= as.numeric(getPrice(mktdataTimestamp,prefer=prefer))) )
+                                {
+                                    txnprice = orderPrice
+                                    txntime = timestamp
+                                } else next() # price did not move through my order, should go to next order 
                             } else {
-                                # price did not move through my order
-                                next() # should go to next order
+                                warning('ignoring order with quantity of zero')
+                                next()
                             }
                         } else if(isBBOmktdata){
                             # check side/qty
@@ -541,36 +552,25 @@
                                 ordersubset[ii,"Order.StatusTime"]<-as.character(timestamp)
                                 next()
                             } 
-                        } else {
-                            # no depth data, either OHLC or BBO, getPrice explicitly using symbol ?
-                            if(orderPrice == getPrice(mktdataTimestamp, symbol=symbol, prefer='price')[,1]){
-                                txnprice = orderPrice
-                                txntime = timestamp
-                            } else next()
                         }
-
                     },
                     stoptrailing = {
                         # if market moved through my price, execute
                         if(orderQty > 0){ # positive quantity 'buy'
-                            if(isBBOmktdata){
-                                prefer='offer'
-                                if(orderPrice >= getPrice(mktdataTimestamp,prefer=prefer)[,1]){ #TODO maybe use last(getPrice) to catch multiple prints on timestamp?
-                                    # price we're willing to pay is higher than the offer price, so execute at the prevailing price
-                                    #txnprice = orderPrice
-                                    txnprice = as.numeric(getPrice(mktdataTimestamp,prefer=prefer)[,1]) #presumes unique timestamps
-                                    txntime = timestamp
-                                } 
+                            if(isBBOmktdata) prefer='offer'
+                            if(orderPrice >= getPrice(mktdataTimestamp,prefer=prefer)[,1]){ #TODO maybe use last(getPrice) to catch multiple prints on timestamp?
+                                # price we're willing to pay is higher than the offer price, so execute at the prevailing price
+                                #txnprice = orderPrice
+                                txnprice = as.numeric(getPrice(mktdataTimestamp,prefer=prefer)[,1]) #presumes unique timestamps
+                                txntime = timestamp
                             } 
                         } else { # negative quantity 'sell'
-                            if(isBBOmktdata){
-                                prefer='bid'
-                                if(orderPrice <= getPrice(mktdataTimestamp,prefer=prefer)[,1]){
-                                    # we're willing to sell at a better price than the bid, so execute at the prevailing price
-                                    # txnprice = orderPrice
-                                    txnprice = as.numeric(getPrice(mktdataTimestamp,prefer=prefer)[,1]) #presumes unique timestamp
-                                    txntime = timestamp
-                                }  
+                            if(isBBOmktdata) prefer='bid'
+                            if(orderPrice <= getPrice(mktdataTimestamp,prefer=prefer)[,1]){
+                                # we're willing to sell at a better price than the bid, so execute at the prevailing price
+                                # txnprice = orderPrice
+                                txnprice = as.numeric(getPrice(mktdataTimestamp,prefer=prefer)[,1]) #presumes unique timestamp
+                                txntime = timestamp
                             } 
                         } 
                         if(isOHLCmktdata){

Modified: pkg/quantstrat/R/rules.R
===================================================================
--- pkg/quantstrat/R/rules.R	2011-09-15 15:26:28 UTC (rev 779)
+++ pkg/quantstrat/R/rules.R	2011-09-16 15:07:53 UTC (rev 780)
@@ -390,11 +390,11 @@
                                 col<-first(colnames(mktdata)[has.Ask(mktdata,which=TRUE)])
                             } else if (isOHLCmktdata) {
                                 col<-first(colnames(mktdata)[has.Hi(mktdata,which=TRUE)])
-                            } else {
-                                # We should never hit this code, but it should help us find any edge cases
-                                # like perhaps we need a has.Price check
-                                stop("no price discernable for stoplimit in applyRules")
+                            } else { #univariate or something built with fn_SpreadBuilder  
+                                col<-first(colnames(mktdata)[grep(prefer, colnames(mktdata))])
+                                # perhaps we need a has.Price check
                             }
+                            if (is.na(col)) stop("no price discernable for stoplimit in applyRules")
                         } else { #sell if mktprice moves below stoplimitorder price
                             relationship="lte" #if Bid or Lo go below threshold, our stop will be filled
                             if(isBBOmktdata) {
@@ -402,9 +402,9 @@
                             } else if (isOHLCmktdata) {
                                 col<-first(colnames(mktdata)[has.Lo(mktdata,which=TRUE)])
                             } else {
-                                # We should never hit this code, but it should help us find any edge cases
-                                stop("no price discernable for stoplimit in applyRules")
-                            }
+                                col<-first(colnames(mktdata)[grep(prefer, colnames(mktdata))])
+                            }    
+                            if (is.na(col)) stop("no price discernable for stoplimit in applyRules")                            
                         } 
                         cross<-sigThreshold(label='tmpstop',column=col,threshold=tmpprice,relationship=relationship)
                         if(any(cross[timespan])){
@@ -427,10 +427,9 @@
                             } else if (isOHLCmktdata) {
                                 col<-first(colnames(mktdata)[has.Lo(mktdata,which=TRUE)])
                             } else {
-                                # We should never hit this code, but it should help us find any edge cases
-                                # like perhaps we need a has.Price check
-                                stop("no price discernable in applyRules")
-                            }
+                                col<-first(colnames(mktdata)[grep(prefer, colnames(mktdata))])
+                            }    
+                            if (is.na(col)) stop("no price discernable for stoplimit in applyRules")
                         } else {
                             #selling
                             relationship="gte" #look for places where Mkt Bid >= our Ask
@@ -439,9 +438,9 @@
                             } else if (isOHLCmktdata) {
                                 col<-first(colnames(mktdata)[has.Hi(mktdata,which=TRUE)])
                             } else {
-                                # We should never hit this code, but it should help us find any edge cases
-                                stop("no price discernable in applyRules")
-                            }
+                                col<-first(colnames(mktdata)[grep(prefer, colnames(mktdata))])
+                            }    
+                            if (is.na(col)) stop("no price discernable for stoplimit in applyRules")
                         }
                         # use sigThreshold
                         cross<-sigThreshold(label='tmplimit',column=col,threshold=tmpprice,relationship=relationship)

Modified: pkg/quantstrat/R/traderules.R
===================================================================
--- pkg/quantstrat/R/traderules.R	2011-09-15 15:26:28 UTC (rev 779)
+++ pkg/quantstrat/R/traderules.R	2011-09-16 15:07:53 UTC (rev 780)
@@ -119,7 +119,7 @@
         )
         if(inherits(orderprice,'try-error')) orderprice<-NULL
         if(length(orderprice>1) & !pricemethod=='maker') orderprice<-last(orderprice[timestamp])
-        if(!is.null(orderprice) && ncol(orderprice) > 1) orderprice <- orderprice[,1]
+        if(!is.null(orderprice) && !is.null(ncol(orderprice))) orderprice <- orderprice[,1]
 
         if(is.null(orderside) & !isTRUE(orderqty == 0)){
             curqty<-getPosQty(Portfolio=portfolio, Symbol=symbol, Date=timestamp)



More information about the Blotter-commits mailing list