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

noreply at r-forge.r-project.org noreply at r-forge.r-project.org
Thu Sep 27 01:09:10 CEST 2012


Author: opentrades
Date: 2012-09-27 01:09:09 +0200 (Thu, 27 Sep 2012)
New Revision: 1195

Modified:
   pkg/quantstrat/R/ruleSignal.R
   pkg/quantstrat/R/rules.R
   pkg/quantstrat/man/ruleSignal.Rd
Log:
- implemented support for mktdata column containing threshold values
- fixed bug in stoptrailing nextIdx computation from dindex



Modified: pkg/quantstrat/R/ruleSignal.R
===================================================================
--- pkg/quantstrat/R/ruleSignal.R	2012-09-23 11:48:25 UTC (rev 1194)
+++ pkg/quantstrat/R/ruleSignal.R	2012-09-26 23:09:09 UTC (rev 1195)
@@ -11,16 +11,15 @@
 #'          \item{'market', 'opside', or 'active'}{ will use the 'ask' price if you're buying and 
 #'            the 'bid' price if you're selling, crossing the market at the time of 
 #'            order entry to attempt to set an aggressive price to get the trade. }
-#' 		   \item{'passive', 'work' or 'join'}{ which will join the 'bid' price if you are buying
-#'      	  or join the 'ask' price if you are selling, passively working to make liquidity 
+#'         \item{'passive', 'work' or 'join'}{ which will join the 'bid' price if you are buying
+#'            or join the 'ask' price if you are selling, passively working to make liquidity 
 #'            at the prevailing market price without crossing the market at time of order entry}
-#' 		   \item{'maker'}{will create a pair of orders for both bid and offer, modeling 
-#' 		      market making activities by having orders on both sides.  
+#'         \item{'maker'}{will create a pair of orders for both bid and offer, modeling 
+#'            market making activities by having orders on both sides.  
 #'            This will then create an Order.Set, and use the \code{threshold} to set the prices for these orders.}
 #'      } 
 #' 
-#' 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{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 
 #' (if any), the order quantity, and the order type.    
@@ -33,7 +32,7 @@
 #' @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
-#' @param threshold numeric or function threshold to apply to trailing stop orders, default NULL, see Details
+#' @param threshold numeric or name of indicator column in mktdata, default NULL, see Details
 #' @param tmult if TRUE, threshold is a percent multiplier for \code{price}, not a scalar to be added/subtracted from price.  threshold will be dynamically converted to a scalar at time of order entry
 #' @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
@@ -49,87 +48,108 @@
 #' @param label rule label, default '', added by \code{\link{applyRules}}
 #' @seealso \code{\link{osNoOp}} , \code{\link{add.rule}}
 #' @export
+
 ruleSignal <- function(data=mktdata, timestamp, sigcol, sigval, orderqty=0, ordertype, orderside=NULL, orderset=NULL, threshold=NULL, tmult=FALSE, replace=TRUE, delay=0.0001, osFUN='osNoOp', pricemethod=c('market','opside','active'), portfolio, symbol, ..., ruletype, TxnFees=0, prefer=NULL, sethold=FALSE, label='')
 {
-    if(!is.function(osFUN)) osFUN<-match.fun(osFUN)
-    #print(paste(symbol,timestamp, sigval))
-    #print(data[timestamp][,sigcol])
-    #browser()
+    if(!is.function(osFUN))
+        osFUN<-match.fun(osFUN)
+
 #   if (!is.na(timestamp) && !is.na(data[timestamp][,sigcol]) && data[timestamp][,sigcol] == sigval) {
-    if (!is.na(timestamp) && (ruletype=='chain' || (!is.na(data[timestamp][,sigcol]) && data[timestamp][,sigcol] == sigval))) {
+    if (!is.na(timestamp) && (ruletype=='chain' || (!is.na(data[timestamp][,sigcol]) && data[timestamp][,sigcol] == sigval)))
+    {
         #calculate order price using pricemethod
         pricemethod<-pricemethod[1] #only use the first if not set by calling function
 
-		if(hasArg(prefer)) prefer=match.call(expand.dots=TRUE)$prefer
-		else prefer = NULL
+        if(hasArg(prefer)) prefer=match.call(expand.dots=TRUE)$prefer
+        else prefer = NULL
 
-		#if(hasArg(TxnFees)) TxnFees=match.call(expand.dots=TRUE)$TxnFees
-		#else TxnFees=0
+        #if(hasArg(TxnFees)) TxnFees=match.call(expand.dots=TRUE)$TxnFees
+        #else TxnFees=0
 
-		switch(pricemethod,
+        # compute threshold
+        if(!is.null(threshold))
+        {
+            if(!is.numeric(threshold))
+            {
+                # threshold should be the name of an indicator column in mktdata
+
+                col.idx <- grep(threshold, colnames(data))
+
+                if(length(col.idx) < 1)
+                    stop(paste('no indicator column in mktdata matches threshold name "', threshold, '"', sep=''))
+                if(length(col.idx) > 1)
+                    stop(paste('more than one indicator column in mktdata matches threshold name "', threshold, '"', sep=''))
+
+                threshold <- as.numeric(data[,col.idx][timestamp])
+            }
+        }
+
+        switch(pricemethod,
                 market = ,
-				opside = ,
-				active = {
+                opside = ,
+                active = {
                     if(is.BBO(data)){
                         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=data, prefer=prefer))[timestamp] 
-				},
-				passive =,
-				work =,
-				join = {
-					if(is.BBO(data)){
-						if (orderqty>0) 
-							prefer='bid'  # we're buying, so work the bid price
-						else
-							prefer='ask'  # we're selling, so work the ask price
-					}
+                    orderprice <- try(getPrice(x=data, prefer=prefer))[timestamp] 
+                },
+                passive =,
+                work =,
+                join = {
+                    if(is.BBO(data)){
+                        if (orderqty>0) 
+                            prefer='bid'  # we're buying, so work the bid price
+                        else
+                            prefer='ask'  # we're selling, so work the ask price
+                    }
                     orderprice <- try(getPrice(x=data, prefer=prefer))[timestamp]
-				},
-				maker = {
-					if(hasArg(price) & length(match.call(expand.dots=TRUE)$price)>1) {
-						# we have prices, just use them
-						orderprice <- try(match.call(expand.dots=TRUE)$price)
-					} else {
-						if(!is.null(threshold)) {
-							baseprice<- last(getPrice(x=data)[timestamp]) # this should get either the last trade price or the Close
-							if(hasArg(tmult) & isTRUE(match.call(expand.dots=TRUE)$tmult)) {
-								baseprice<- last(getPrice(x=data)[timestamp]) # this should get either the last trade price or the Close
-								# threshold is a multiplier of current price
-								if (length(threshold)>1){
-									orderprice <- baseprice * threshold # assume the user has set proper threshold multipliers for each side
-								} else {
-									orderprice <- c(baseprice*threshold,baseprice*(1+1-threshold)) #just bracket on both sides
-								}
-							} else {
-								# tmult is FALSE or NULL, threshold is numeric
-								if (length(threshold)>1){
-									orderprice <- baseprice + threshold # assume the user has set proper threshold numerical offsets for each order
-								} else {
-									orderprice <- c(baseprice+threshold,baseprice+(-threshold)) #just bracket on both sides
-								}
-							}
-						} else{
-							# no threshold, put it on the averages?
-							stop('maker orders without specified prices and without threholds not (yet?) supported')
-							if(is.BBO(data)){
+                },
+                maker = {
+                    if(hasArg(price) & length(match.call(expand.dots=TRUE)$price)>1) {
+                        # we have prices, just use them
+                        orderprice <- try(match.call(expand.dots=TRUE)$price)
+                    } else {
+                        if(!is.null(threshold)) {
+                            baseprice<- last(getPrice(x=data)[timestamp]) # this should get either the last trade price or the Close
+                            if(hasArg(tmult) & isTRUE(match.call(expand.dots=TRUE)$tmult)) {
+                                baseprice<- last(getPrice(x=data)[timestamp]) # this should get either the last trade price or the Close
+                                # threshold is a multiplier of current price
+                                if (length(threshold)>1){
+                                    orderprice <- baseprice * threshold # assume the user has set proper threshold multipliers for each side
+                                } else {
+                                    orderprice <- c(baseprice*threshold,baseprice*(1+1-threshold)) #just bracket on both sides
+                                }
+                            } else {
+                                # tmult is FALSE or NULL, threshold is numeric
+                                if (length(threshold)>1){
+                                    orderprice <- baseprice + threshold # assume the user has set proper threshold numerical offsets for each order
+                                } else {
+                                    orderprice <- c(baseprice+threshold,baseprice+(-threshold)) #just bracket on both sides
+                                }
+                            }
+                        } else{
+                            # no threshold, put it on the averages?
+                            stop('maker orders without specified prices and without threholds not (yet?) supported')
+                            if(is.BBO(data)){
 
-							} else {
+                            } else {
 
-							}
-						}
-					}
-					if(length(orderqty)==1) orderqty <- c(orderqty,-orderqty) #create paired market maker orders at the same size
-				}
-        )
+                            }
+                        }
+                    }
+                    if(length(orderqty)==1) orderqty <- c(orderqty,-orderqty) #create paired market maker orders at the same size
+                }
+        ) # end switch
+
         if(inherits(orderprice,'try-error')) orderprice<-NULL
         if(length(orderprice>1) && !pricemethod=='maker') orderprice<-last(orderprice[timestamp])
         if(!is.null(orderprice) && !is.null(ncol(orderprice))) orderprice <- orderprice[,1]
 
-        if(is.null(orderside) & !isTRUE(orderqty == 0)){
+        if(is.null(orderside) & !isTRUE(orderqty == 0))
+        {
             curqty<-getPosQty(Portfolio=portfolio, Symbol=symbol, Date=timestamp)
             if (curqty>0 ){
                 #we have a long position
@@ -146,34 +166,35 @@
             }
         }
 
-	if(is.null(orderset)) orderset=NA
+        if(is.null(orderset)) orderset=NA
 
-	## now size the order
-	#TODO add fancy formals matching for osFUN
-	if(orderqty!='all')
-	{
-		orderqty <- osFUN(strategy=strategy, data=data, timestamp=timestamp, orderqty=orderqty, ordertype=ordertype, orderside=orderside, portfolio=portfolio, symbol=symbol,...=...,ruletype=ruletype, orderprice=as.numeric(orderprice))
-    }
+        
+        ## now size the order
+        #TODO add fancy formals matching for osFUN
+        if(orderqty!='all')
+        {
+            orderqty <- osFUN(strategy=strategy, data=data, timestamp=timestamp, orderqty=orderqty, ordertype=ordertype, orderside=orderside, portfolio=portfolio, symbol=symbol,...=...,ruletype=ruletype, orderprice=as.numeric(orderprice))
+        }
 
-	if(!is.null(orderqty) && orderqty!=0 && !is.null(orderprice)) #orderprice could have length > 1
-	{
-		addOrder(portfolio=portfolio, 
-                 symbol=symbol, 
-                 timestamp=timestamp, 
-                 qty=orderqty, 
-                 price=as.numeric(orderprice), 
-                 ordertype=ordertype, 
-                 side=orderside, 
-                 orderset=orderset, 
-                 threshold=threshold, 
-                 status="open", 
-                 replace=replace , 
-                 delay=delay, 
-                 tmult=tmult, 
-                 ...=..., 
-                 prefer=prefer, 
-                 TxnFees=TxnFees,
-                 label=label)
+        if(!is.null(orderqty) && orderqty!=0 && !is.null(orderprice)) #orderprice could have length > 1
+        {
+            addOrder(portfolio=portfolio, 
+                     symbol=symbol, 
+                     timestamp=timestamp, 
+                     qty=orderqty, 
+                     price=as.numeric(orderprice), 
+                     ordertype=ordertype, 
+                     side=orderside, 
+                     orderset=orderset, 
+                     threshold=threshold, 
+                     status="open", 
+                     replace=replace , 
+                     delay=delay, 
+                     tmult=tmult, 
+                     ...=..., 
+                     prefer=prefer, 
+                     TxnFees=TxnFees,
+                     label=label)
         }
     }
     if(sethold) hold <<- TRUE

Modified: pkg/quantstrat/R/rules.R
===================================================================
--- pkg/quantstrat/R/rules.R	2012-09-23 11:48:25 UTC (rev 1194)
+++ pkg/quantstrat/R/rules.R	2012-09-26 23:09:09 UTC (rev 1195)
@@ -394,7 +394,7 @@
             } else {
 
                 if(length(grep('^market$', ordersubset[oo.idx,'Order.Type'])) > 0)
-		{
+                {
                     # if block above had a prefer exclusion, as below:
                     # || hasArg('prefer')
                     # 'prefer' arguments would loop through all observations.  
@@ -408,204 +408,205 @@
                     #return(curIndex) # move to next index, a market order in this index would have trumped any other open order
                 } 
 
-		stoplimitorders <- grep('^stoplimit$', ordersubset[oo.idx,'Order.Type'])
-		for(slorder in stoplimitorders)
-		{
-		    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==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
-		    }
-		    tmpqty<-as.numeric(tmpqty)
-		    tmpprice <- as.numeric(ordersubset[oo.idx[slorder],'Order.Price'])
-		    if (tmpqty > 0) { #buy if mktprice moves above stoplimitorder price
-			relationship='gte'  #if the Ask or Hi go above threshold our stop will be filled
-			if(isBBOmktdata) {
-			    col<-first(colnames(mktdata)[has.Ask(mktdata,which=TRUE)])
-			} else if (isOHLCmktdata) {
-			    col<-first(colnames(mktdata)[has.Hi(mktdata,which=TRUE)])
-			} 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) {
-			    col<-first(colnames(mktdata)[has.Bid(mktdata,which=TRUE)])
-			} else if (isOHLCmktdata) {
-			    col<-first(colnames(mktdata)[has.Lo(mktdata,which=TRUE)])
-			} else {
-			    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])){
-			# find first index that would cross after this index
-			newidx <- curIndex + which(cross[timespan])[1] - 1
-			# insert that into dindex
-			assign.dindex(c(get.dindex(),newidx))                  
-		    }
-		}
+                stoplimitorders <- grep('^stoplimit$', ordersubset[oo.idx,'Order.Type'])
+                for(slorder in stoplimitorders)
+                {
+                    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==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
+                    }
+                    tmpqty<-as.numeric(tmpqty)
+                    tmpprice <- as.numeric(ordersubset[oo.idx[slorder],'Order.Price'])
+                    if (tmpqty > 0) { #buy if mktprice moves above stoplimitorder price
+                    relationship='gte'  #if the Ask or Hi go above threshold our stop will be filled
+                    if(isBBOmktdata) {
+                        col<-first(colnames(mktdata)[has.Ask(mktdata,which=TRUE)])
+                    } else if (isOHLCmktdata) {
+                        col<-first(colnames(mktdata)[has.Hi(mktdata,which=TRUE)])
+                    } 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) {
+                        col<-first(colnames(mktdata)[has.Bid(mktdata,which=TRUE)])
+                    } else if (isOHLCmktdata) {
+                        col<-first(colnames(mktdata)[has.Lo(mktdata,which=TRUE)])
+                    } else {
+                        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])){
+                    # find first index that would cross after this index
+                    newidx <- curIndex + which(cross[timespan])[1] - 1
+                    # insert that into dindex
+                    assign.dindex(c(get.dindex(),newidx))                  
+                    }
+                }
 
-		limitorders<-grep('^limit$', ordersubset[oo.idx,'Order.Type'])
-		for(lorder in limitorders)
-		{
-		    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==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
-		    }
-		    tmpqty<-as.numeric(tmpqty)
-		    
-		    tmpprice<-as.numeric(ordersubset[oo.idx[lorder],'Order.Price'])
-		    
-		    if(tmpqty>0){
-			#buying
-			relationship="lte" #look for places where Mkt Ask <= our Bid
-			if(isBBOmktdata) {
-			    col<-first(colnames(mktdata)[has.Ask(mktdata,which=TRUE)])
-			} else if (isOHLCmktdata) {
-			    col<-first(colnames(mktdata)[has.Lo(mktdata,which=TRUE)])
-			} else {
-			    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
-			if(isBBOmktdata) {
-			    col<-first(colnames(mktdata)[has.Bid(mktdata,which=TRUE)])
-			} else if (isOHLCmktdata) {
-			    col<-first(colnames(mktdata)[has.Hi(mktdata,which=TRUE)])
-			} else {
-			    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)
-		    if(any(cross[timespan])){
-			# find first index that would cross after this index
-			newidx <- curIndex + which(cross[timespan])[1] #- 1  #curIndex/timestamp was 1 in the subset, we need a -1 offset?
-			#if there are is no cross curIndex will be incremented on line 496
-			# with curIndex<-min(dindex[dindex>curIndex]).                            
-			#we cannot get filled at this timestamp. The soonest we could get filled is next timestamp...
-			#see also that market order increments curIndex before returning it. Going by the docs,
-			#I think this is by design. i.e. no instant fills. -gsee
-			
-			# insert that into dindex
-			assign.dindex(c(get.dindex(),newidx))                  
-		    } else{
-			# no cross, move ahead
-			# nidx=TRUE #WHY WAS THIS HERE?
-		    }
-		} # end loop over open limit orders
+                limitorders<-grep('^limit$', ordersubset[oo.idx,'Order.Type'])
+                for(lorder in limitorders)
+                {
+                    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==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
+                    }
+                    tmpqty<-as.numeric(tmpqty)
+                    
+                    tmpprice<-as.numeric(ordersubset[oo.idx[lorder],'Order.Price'])
+                    
+                    if(tmpqty>0){
+                    #buying
+                    relationship="lte" #look for places where Mkt Ask <= our Bid
+                    if(isBBOmktdata) {
+                        col<-first(colnames(mktdata)[has.Ask(mktdata,which=TRUE)])
+                    } else if (isOHLCmktdata) {
+                        col<-first(colnames(mktdata)[has.Lo(mktdata,which=TRUE)])
+                    } else {
+                        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
+                    if(isBBOmktdata) {
+                        col<-first(colnames(mktdata)[has.Bid(mktdata,which=TRUE)])
+                    } else if (isOHLCmktdata) {
+                        col<-first(colnames(mktdata)[has.Hi(mktdata,which=TRUE)])
+                    } else {
+                        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)
+                    if(any(cross[timespan])){
+                    # find first index that would cross after this index
+                    newidx <- curIndex + which(cross[timespan])[1] #- 1  #curIndex/timestamp was 1 in the subset, we need a -1 offset?
+                    #if there are is no cross curIndex will be incremented on line 496
+                    # with curIndex<-min(dindex[dindex>curIndex]).                            
+                    #we cannot get filled at this timestamp. The soonest we could get filled is next timestamp...
+                    #see also that market order increments curIndex before returning it. Going by the docs,
+                    #I think this is by design. i.e. no instant fills. -gsee
+                    
+                    # insert that into dindex
+                    assign.dindex(c(get.dindex(),newidx))                  
+                    } else{
+                    # no cross, move ahead
+                    # nidx=TRUE #WHY WAS THIS HERE?
+                    }
+                } # end loop over open limit orders
 
-        trailorders<-grep('^stoptrailing$', ordersubset[oo.idx,'Order.Type'])
-		for(torder in trailorders)
-		{
-		    dindex<-get.dindex()
-		    firsttime<-NULL
-		    neworders<-NULL
-		    onum<-oo.idx[torder]
-		    orderThreshold <- as.numeric(ordersubset[onum,'Order.Threshold'])
-		    tmpqty<-ordersubset[onum,'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==0) {
-			#no position, so do some sleight of hand to figure out when the index may be needed
-			side <- ordersubset[oo.idx[torder],'Order.Side']
-			if(side=='long') tmpqty=-1
-			else tmpqty=1
-		    }
-		    tmpqty<-as.numeric(tmpqty)
-		    if (tmpqty==0) {
-			#no position, so do some sleight of hand to figure out when the index may be needed
-			side <- ordersubset[onum,'Order.Side']
-			if(side=='long') tmpqty=-1
-			else tmpqty=1
-		    }
-		    tmpqty<-as.numeric(tmpqty)
-		    tmpprice<-as.numeric(ordersubset[onum,'Order.Price'])
-		    tmpidx <- format(index(ordersubset[onum,]), "%Y-%m-%d %H:%M:%OS6") #this is the time the order was entered
-		    #print(tmpidx)
-		    if(isBBOmktdata) {
-			if(tmpqty > 0){ # positive quantity 'buy'
-			    prefer='offer'
-			} else {
-			    prefer='bid'
-			}
-		    } else if (isOHLCmktdata) {
-			prefer='close'
-		    } 
-		    dindex<-get.dindex()
-		    if(is.null(firsttime)) firsttime<-timestamp
-		    nextidx<-min(dindex[dindex>curIndex])
-		    if(length(nextidx)){
-			nextstamp <- format(index(mktdata[nextidx,]), "%Y-%m-%d %H:%M:%OS6")
-			#print(nextstamp)
-			timespan <- paste(format(firsttime, "%Y-%m-%d %H:%M:%OS6"),"::",nextstamp,sep='')
-			#get the subset of prices
-			mkt_price_series <-getPrice(mktdata[timespan],prefer=prefer)
-			col<-first(colnames(mkt_price_series))
-			orderloop<-TRUE
-		    } else {
-			orderloop<-FALSE
-		    }
-		    if(tmpqty > 0){ # positive quantity 'buy'
-			move_order <- ifelse( (mkt_price_series+orderThreshold) < tmpprice, TRUE, FALSE )
-			#this ifelse creates a logical xts vector 
-			relationship="gte"
-		    } else {  # negative quantity 'sell'
-			move_order <- ifelse( (mkt_price_series+orderThreshold) > tmpprice, TRUE, FALSE )
-			relationship="lte"
-		    }
-		    tmpidx<-NULL
-		    if(any(move_order)){
-			dindex<-get.dindex()
-			#print(firsttime)
-			# find first index where we would move an order
-			orderidx<-first(which(move_order)) 
-			if(is.null(tmpidx))
-			    tmpidx <- format(index(move_order[orderidx,]), "%Y-%m-%d %H:%M:%OS6")
-			trailspan <- paste(format(firsttime, "%Y-%m-%d %H:%M:%OS6"),"::",tmpidx,sep='')
-			#make sure we don't cross before then 
-			# use sigThreshold
-			cross<-sigThreshold(data=mkt_price_series, label='tmptrail',column=col,threshold=tmpprice,relationship=relationship)
-			# find first index that would cross after this index
-			if (any(cross[trailspan])){
-			    newidx <- curIndex + which(cross[trailspan])[1] - 1  #curIndex/firsttime was 1 in the subset, we need a -1 offset?
-			    newidx <- index(mktdata[index(which(cross[trailspan])[1]),which.i=TRUE])
-			    # insert that into dindex
-			    assign.dindex(c(get.dindex(),newidx))
-			} else {
-			    #if we don't cross, do this
-			    moveidx<-index(mktdata[index(move_order[orderidx,]),which.i=TRUE])
-			    assign.dindex(c(get.dindex(),moveidx))
-			}    
-		    } # end any(move_order) check                            
-		} # end loop over open trailing orders
+                trailorders<-grep('^stoptrailing$', ordersubset[oo.idx,'Order.Type'])
+                for(torder in trailorders)
+                {
+                    dindex<-get.dindex()
+                    firsttime<-NULL
+                    neworders<-NULL
+                    onum<-oo.idx[torder]
+                    orderThreshold <- as.numeric(ordersubset[onum,'Order.Threshold'])
+                    tmpqty<-ordersubset[onum,'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==0) {
+                        #no position, so do some sleight of hand to figure out when the index may be needed
+                        side <- ordersubset[oo.idx[torder],'Order.Side']
+                        if(side=='long') tmpqty=-1
+                        else tmpqty=1
+                    }
+                    tmpqty<-as.numeric(tmpqty)
+                    if (tmpqty==0) {
+                        #no position, so do some sleight of hand to figure out when the index may be needed
+                        side <- ordersubset[onum,'Order.Side']
+                        if(side=='long') tmpqty=-1
+                        else tmpqty=1
+                    }
+                    tmpqty<-as.numeric(tmpqty)
+                    tmpprice<-as.numeric(ordersubset[onum,'Order.Price'])
+                    tmpidx <- format(index(ordersubset[onum,]), "%Y-%m-%d %H:%M:%OS6") #this is the time the order was entered
+                    #print(tmpidx)
+                    if(isBBOmktdata) {
+                        if(tmpqty > 0){ # positive quantity 'buy'
+                            prefer='offer'
+                        } else {
+                            prefer='bid'
+                        }
+                    } else if (isOHLCmktdata) {
+                        prefer='close'
+                    } 
+                    dindex<-get.dindex()
+                    if(is.null(firsttime)) firsttime<-timestamp
+
+                    ddindex <- dindex[dindex>curIndex]
+                    if(length(ddindex) == 0)
+                        return(FALSE)
+
+                    nextidx <- min(ddindex)
+                    nextstamp <- format(index(mktdata[nextidx,]), "%Y-%m-%d %H:%M:%OS6")
+                    timespan <- paste(format(firsttime, "%Y-%m-%d %H:%M:%OS6"),"::",nextstamp,sep='')
+
+                    #get the subset of prices
+                    mkt_price_series <-getPrice(mktdata[timespan],prefer=prefer)
+                    col<-first(colnames(mkt_price_series))
+
+                    if(tmpqty > 0){ # positive quantity 'buy'
+                        move_order <- ifelse( (mkt_price_series+orderThreshold) < tmpprice, TRUE, FALSE )
+                        #this ifelse creates a logical xts vector 
+                        relationship="gte"
+                    } else {  # negative quantity 'sell'
+                        move_order <- ifelse( (mkt_price_series+orderThreshold) > tmpprice, TRUE, FALSE )
+                        relationship="lte"
+                    }
+                    tmpidx<-NULL
+                    if(any(move_order)){
+                        dindex<-get.dindex()
+                        #print(firsttime)
+                        # find first index where we would move an order
+                        orderidx<-first(which(move_order)) 
+                        if(is.null(tmpidx))
+                            tmpidx <- format(index(move_order[orderidx,]), "%Y-%m-%d %H:%M:%OS6")
+                        trailspan <- paste(format(firsttime, "%Y-%m-%d %H:%M:%OS6"),"::",tmpidx,sep='')
+                        #make sure we don't cross before then 
+                        # use sigThreshold
[TRUNCATED]

To get the complete diff run:
    svnlook diff /svnroot/blotter -r 1195


More information about the Blotter-commits mailing list