[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