[Blotter-commits] r982 - pkg/quantstrat/R
noreply at r-forge.r-project.org
noreply at r-forge.r-project.org
Sun Mar 25 18:09:52 CEST 2012
Author: braverock
Date: 2012-03-25 18:09:52 +0200 (Sun, 25 Mar 2012)
New Revision: 982
Added:
pkg/quantstrat/R/ruleOrderProc.R
Modified:
pkg/quantstrat/R/orders.R
Log:
- separate ruleOrderProc into its own file
- add TZ patch provided by Jan Humme <jan <at> opentrades <dot> nl>
Modified: pkg/quantstrat/R/orders.R
===================================================================
--- pkg/quantstrat/R/orders.R 2012-03-24 16:22:35 UTC (rev 981)
+++ pkg/quantstrat/R/orders.R 2012-03-25 16:09:52 UTC (rev 982)
@@ -363,313 +363,12 @@
orderbook <- getOrderBook(portfolio)
orderbook[[portfolio]][[symbol]][updatedorders,"Order.Status"]<-newstatus
- orderbook[[portfolio]][[symbol]][updatedorders,"Order.StatusTime"]<-as.character(statustimestamp)
+ orderbook[[portfolio]][[symbol]][updatedorders,"Order.StatusTime"]<- as.character(as.POSIXlt(statustimestamp, Sys.getenv('TZ')))
# assign order book back into place (do we need a non-exported "put" function?)
assign(paste("order_book",portfolio,sep='.'),orderbook,envir=.strategy)
}
}
-
-#' process open orders at time \emph{t}, generating transactions or new orders
-#'
-#' The ruleOrderProc function is effectively the default fill simulator for quantstrat.
-#' This function is meant to be sufficient for backtesting most strategies,
-#' but would need to be replaced for production use. It provides the interface
-#' for taking the order book and determining when orders become trades.
-#'
-#' For the purposes of backtesting, and compatibility with the trade accounting in
-#' \code{blotter}, this function will not allow a transaction to cross your current
-#' position through zero. The accounting rules for realizing gains in such cases
-#' are more complicated than we wish to support. Also, many brokers will break, revise,
-#' or split such transactions for the same reason. If you wish to do a "stop and reverse"
-#' system, first stop (flatten), and then reverse (initiate a new position).
-#'
-#' This function would need to be revised or replaced for connection to a live trading infrastructure.
-#' In a production mode, you would replace the \code{\link{addOrder}} function
-#' with a custom function to connect to your market infrastructure.
-#' In that case, you might need to add additional code to your strategy,
-#' or overload functions for checking position.
-#'
-#' Note that this function is called by default in the 'orders' slot of the
-#' \code{\link{applyRules}} processing. If you have defined another order
-#' processing rule, it will \emph{replace} this function. If you want your
-#' custom order rule and ruleOrderProc to both be called, you will need
-#' explicitly add a rule to call ruleOrderProc either before or after your
-#' custom order processing function.
-#'
-#' We would like to model slippage here via \code{slippageFUN}. Code contributions, suggestions,
-#' and requests appreciated.
-#'
-#' @concept fill simulator
-#' @concept orders
-#' @concept backtest
-#' @concept fills
-#'
-#' This function is meant to be sufficient for backtesting many/most strategies,
-#' but would need to be replaced for production use. It provides the interface
-#' for taking the order book and determining when orders become trades.
-#'
-#' @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 or BBO) should match these
-#' @param mktdata an xts object containing market data. depending on indicators, may need to be in OHLCV or BBO formats, default NULL
-#' @param timespan xts-style character timespan to be the period to find orders to process in
-#' @param ordertype one of NULL, "market","limit","stoplimit", or "stoptrailing" default NULL
-#' @param ... any other passthru parameters
-#' @param slippageFUN default NULL, not yet implemented
-#' @seealso add.rule
-#' @seealso applyRules
-#' @seealso getOrderBook
-#' @seealso addOrder
-#' @seealso updateOrders
-#' @export
-ruleOrderProc <- function(portfolio, symbol, mktdata, timespan=NULL, ordertype=NULL, ..., slippageFUN=NULL)
-{
- if(is.null(timespan)) return()
- orderbook <- getOrderBook(portfolio)
- ordersubset <- orderbook[[portfolio]][[symbol]]
-
- # 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])
- timestamp <- time(last(mktdata[timespan]))
- #switch on frequency
- freq = periodicity(mktdata)
- neworders<-NULL
- mktdataTimestamp <- mktdata[timestamp]
- #str(mktdataTimestamp)
- # Should we only keep the last observation per time stamp?
- if( NROW(mktdataTimestamp) > 1 ) mktdataTimestamp <- last(mktdataTimestamp)
- isOHLCmktdata <- is.OHLC(mktdata)
- isBBOmktdata <- is.BBO(mktdata)
- for (ii in procorders ){
- txnprice=NULL
- txnfees=ordersubset[ii,"Txn.Fees"]
- orderPrice <- as.numeric(ordersubset[ii,"Order.Price"])
- orderQty <- as.numeric(ordersubset[ii,"Order.Qty"])
- orderThreshold <- as.numeric(ordersubset[ii,"Order.Threshold"])
- # mktdataTimestamp <- mktdata[timestamp]
- #FIXME Should we only keep the last observation per time stamp?
- #if( NROW(mktdataTimestamp) > 1 ) mktdataTimestamp <- last(mktdataTimestamp)
- orderType <- ordersubset[ii,"Order.Type"]
-
- switch(orderType,
- market = {
- switch(freq$scale,
- yearly = ,
- quarterly = ,
- monthly = ,
- 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]), prefer=prefer)[,1])
- }, #end daily
- {
- txntime = timestamp
- if (isBBOmktdata) {
- #An ordertype of market will *almost* trump pricemethod here. orderPrice was determined using pricemethod.
- #but, for buy orders you'll be filled at either orderPrice or the current mkt ask -- whichever is worse.
- #and, for sell orders you'll be filled at either orderPrice or the current mkt bid -- whichever is worse.
- if(orderQty > 0){ # positive quantity 'buy'
- #fill at max(orderPrice,newMktAsk price)
- txnprice = max(orderPrice, as.numeric(getPrice(mktdataTimestamp,prefer='ask')[,1]))
- } else { # negative quantity 'sell'
- 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, prefer=prefer)[,1]) #filled at 'price'
- }) # end switch on frequency
- },
- limit= ,
- stoplimit =,
- iceberg = {
- if (!isBBOmktdata) { #(isOHLCmktdata){
- if( orderType == 'iceberg'){
- stop("iceberg orders only supported for BBO data")
- }
- # check to see if price moved through the limit
- if(orderQty > 0 || (orderQty < 0 && orderType == 'stoplimit') ) {
- # buy limit, or sell stoplimit
- 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 || (orderQty > 0 && orderType == 'stoplimit')) {
- # sell limit or buy stoplimit
- 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 {
- warning('ignoring order with quantity of zero')
- next()
- }
- } else if(isBBOmktdata){
- # check side/qty
- if(orderQty > 0){ # positive quantity 'buy'
- if (orderType == 'stoplimit') {
- if(orderPrice <= as.numeric(getPrice(mktdataTimestamp,prefer='ask')[,1])){
- # mktprice moved above our stop buy price
- txnprice = orderPrice #assume we got filled at our stop price
- #txnprice = as.numeric(getPrice(mktdataTimestamp,prefer='ask')[,1]) #presumes unique timestamps
- txntime = timestamp
- } else next()
- } else {
- if(orderPrice >= as.numeric(getPrice(mktdataTimestamp,prefer='ask')[,1])){
- # 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='ask')[,1]) #presumes unique timestamps
- txntime = timestamp
- } else next()
- }
- } else { # negative quantity 'sell'
- if (orderType == 'stoplimit') {
- if(orderPrice >= as.numeric(getPrice(mktdataTimestamp,prefer='bid')[,1])){
- # mktprice moved below our stop sell price
- txnprice = orderPrice #assumption is that we're filled at our stop price
- #txnprice = as.numeric(getPrice(mktdataTimestamp,prefer='bid')[,1]) #presumes unique timestamp
- txntime = timestamp
- } else next()
- } else {
- if(orderPrice <= as.numeric(getPrice(mktdataTimestamp,prefer='bid')[,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='bid')[,1]) #presumes unique timestamp
- txntime = timestamp
- } else next()
- }
- }
-
-
- if( orderType == 'iceberg'){
- #we've transacted, so the old order was closed, put in a new one
- neworder<-addOrder(portfolio=portfolio,
- symbol=symbol,
- timestamp=timestamp,
- qty=orderQty,
- price=as.numeric(getPrice(mktdataTimestamp,prefer=prefer)[,1]),
- ordertype=orderType,
- side=ordersubset[ii,"Order.Side"],
- threshold=orderThreshold,
- status="open",
- replace=FALSE, return=TRUE,
- ,...=..., TxnFees=txnfees)
- if (is.null(neworders)) neworders=neworder else neworders = rbind(neworders,neworder)
- ordersubset[ii,"Order.Status"]<-'replaced'
- ordersubset[ii,"Order.StatusTime"]<-as.character(timestamp)
- 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
- }
- } 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(isOHLCmktdata){
- # check to see if price moved through the limit
- if( orderPrice > as.numeric(Lo(mktdataTimestamp)) &
- orderPrice < as.numeric(Hi(mktdataTimestamp)) )
- {
- txnprice = orderPrice
- txntime = timestamp
- }
- }
- # if market is beyond price+(-threshold), replace order
- if(is.null(txnprice)) {
- #print("here")
- # we didn't trade, so check to see if we need to move the stop
- # first figure out how to find a price
- if (isOHLCmktdata){
- prefer='close'
- } else if(isBBOmktdata) {
- if(orderQty > 0){
- prefer='offer'
- } else {
- prefer='bid'
- }
- } else {
- prefer=NULL # see if getPrice can figure it out
- }
- # check if we need to move the stop
- mvstop=FALSE
- if(orderQty > 0){ # positive quantity 'buy'
- if( as.numeric(last(getPrice(x=mktdataTimestamp,prefer=prefer)[,1]))+orderThreshold < orderPrice ) mvstop=TRUE
- } else { # negative quantity 'sell'
- if( as.numeric(last(getPrice(x=mktdataTimestamp,prefer=prefer)[,1]))+orderThreshold > orderPrice ) mvstop=TRUE
-
- }
- if( isTRUE(mvstop) ){
- neworder<-addOrder(portfolio=portfolio,
- symbol=symbol,
- timestamp=timestamp,
- qty=orderQty,
- price=as.numeric(getPrice(mktdataTimestamp,prefer=prefer)[,1]),
- ordertype=orderType,
- side=ordersubset[ii,"Order.Side"],
- threshold=orderThreshold,
- status="open",
- replace=FALSE, return=TRUE,
- ,...=..., TxnFees=txnfees)
- if (is.null(neworders)) neworders=neworder else neworders = rbind(neworders,neworder)
- ordersubset[ii,"Order.Status"]<-'replaced'
- ordersubset[ii,"Order.StatusTime"]<-as.character(timestamp)
- next()
- }
- }
- # else next
- }
- )
- if(!is.null(txnprice) && !isTRUE(is.na(txnprice))) {
- #make sure we don't cross through zero
- pos<-getPosQty(portfolio,symbol,timestamp)
- if ( (pos > 0 && orderQty < -pos) || (pos < 0 && orderQty > -pos) ) {
- warning("orderQty of ",orderQty,
- " would cross through zero, adjusting qty to ",-pos)
- orderQty <- -pos
- }
- if (orderQty != 0) {
- #now add the transaction
- addTxn(Portfolio=portfolio, Symbol=symbol, TxnDate=txntime,
- TxnQty=orderQty, TxnPrice=txnprice , ...=..., TxnFees=txnfees)
- ordersubset[ii,"Order.Status"]<-'closed'
- ordersubset[ii,"Order.StatusTime"]<-as.character(timestamp)
- }
- }
- } #end loop over open orders
- if(!is.null(neworders)) ordersubset=rbind(ordersubset,neworders)
-
- # now put the orders back in
- # assign order book back into place (do we need a non-exported "put" function?)
- orderbook[[portfolio]][[symbol]] <- ordersubset
- assign(paste("order_book",portfolio,sep='.'),orderbook,envir=.strategy)
- } # end check for open orders
-}
###############################################################################
# R (http://r-project.org/) Quantitative Strategy Model Framework
#
Copied: pkg/quantstrat/R/ruleOrderProc.R (from rev 981, pkg/quantstrat/R/orders.R)
===================================================================
--- pkg/quantstrat/R/ruleOrderProc.R (rev 0)
+++ pkg/quantstrat/R/ruleOrderProc.R 2012-03-25 16:09:52 UTC (rev 982)
@@ -0,0 +1,313 @@
+#' process open orders at time \emph{t}, generating transactions or new orders
+#'
+#' The ruleOrderProc function is effectively the default fill simulator for quantstrat.
+#' This function is meant to be sufficient for backtesting most strategies,
+#' but would need to be replaced for production use. It provides the interface
+#' for taking the order book and determining when orders become trades.
+#'
+#' For the purposes of backtesting, and compatibility with the trade accounting in
+#' \code{blotter}, this function will not allow a transaction to cross your current
+#' position through zero. The accounting rules for realizing gains in such cases
+#' are more complicated than we wish to support. Also, many brokers will break, revise,
+#' or split such transactions for the same reason. If you wish to do a "stop and reverse"
+#' system, first stop (flatten), and then reverse (initiate a new position).
+#'
+#' This function would need to be revised or replaced for connection to a live trading infrastructure.
+#' In a production mode, you would replace the \code{\link{addOrder}} function
+#' with a custom function to connect to your market infrastructure.
+#' In that case, you might need to add additional code to your strategy,
+#' or overload functions for checking position.
+#'
+#' Note that this function is called by default in the 'orders' slot of the
+#' \code{\link{applyRules}} processing. If you have defined another order
+#' processing rule, it will \emph{replace} this function. If you want your
+#' custom order rule and ruleOrderProc to both be called, you will need
+#' explicitly add a rule to call ruleOrderProc either before or after your
+#' custom order processing function.
+#'
+#' We would like to model slippage here via \code{slippageFUN}. Code contributions, suggestions,
+#' and requests appreciated.
+#'
+#' @concept fill simulator
+#' @concept orders
+#' @concept backtest
+#' @concept fills
+#'
+#' This function is meant to be sufficient for backtesting many/most strategies,
+#' but would need to be replaced for production use. It provides the interface
+#' for taking the order book and determining when orders become trades.
+#'
+#' @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 or BBO) should match these
+#' @param mktdata an xts object containing market data. depending on indicators, may need to be in OHLCV or BBO formats, default NULL
+#' @param timespan xts-style character timespan to be the period to find orders to process in
+#' @param ordertype one of NULL, "market","limit","stoplimit", or "stoptrailing" default NULL
+#' @param ... any other passthru parameters
+#' @param slippageFUN default NULL, not yet implemented
+#' @seealso add.rule
+#' @seealso applyRules
+#' @seealso getOrderBook
+#' @seealso addOrder
+#' @seealso updateOrders
+#' @export
+ruleOrderProc <- function(portfolio, symbol, mktdata, timespan=NULL, ordertype=NULL, ..., slippageFUN=NULL)
+{
+ if(is.null(timespan)) return()
+ orderbook <- getOrderBook(portfolio)
+ ordersubset <- orderbook[[portfolio]][[symbol]]
+
+ # 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])
+ timestamp <- time(last(mktdata[timespan]))
+ #switch on frequency
+ freq = periodicity(mktdata)
+ neworders<-NULL
+ mktdataTimestamp <- mktdata[timestamp]
+ #str(mktdataTimestamp)
+ # Should we only keep the last observation per time stamp?
+ if( NROW(mktdataTimestamp) > 1 ) mktdataTimestamp <- last(mktdataTimestamp)
+ isOHLCmktdata <- is.OHLC(mktdata)
+ isBBOmktdata <- is.BBO(mktdata)
+ for (ii in procorders ){
+ txnprice=NULL
+ txnfees=ordersubset[ii,"Txn.Fees"]
+ orderPrice <- as.numeric(ordersubset[ii,"Order.Price"])
+ orderQty <- as.numeric(ordersubset[ii,"Order.Qty"])
+ orderThreshold <- as.numeric(ordersubset[ii,"Order.Threshold"])
+ # mktdataTimestamp <- mktdata[timestamp]
+ #FIXME Should we only keep the last observation per time stamp?
+ #if( NROW(mktdataTimestamp) > 1 ) mktdataTimestamp <- last(mktdataTimestamp)
+ orderType <- ordersubset[ii,"Order.Type"]
+
+ switch(orderType,
+ market = {
+ switch(freq$scale,
+ yearly = ,
+ quarterly = ,
+ monthly = ,
+ 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]), prefer=prefer)[,1])
+ }, #end daily
+ {
+ txntime = timestamp
+ if (isBBOmktdata) {
+ #An ordertype of market will *almost* trump pricemethod here. orderPrice was determined using pricemethod.
+ #but, for buy orders you'll be filled at either orderPrice or the current mkt ask -- whichever is worse.
+ #and, for sell orders you'll be filled at either orderPrice or the current mkt bid -- whichever is worse.
+ if(orderQty > 0){ # positive quantity 'buy'
+ #fill at max(orderPrice,newMktAsk price)
+ txnprice = max(orderPrice, as.numeric(getPrice(mktdataTimestamp,prefer='ask')[,1]))
+ } else { # negative quantity 'sell'
+ 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, prefer=prefer)[,1]) #filled at 'price'
+ }) # end switch on frequency
+ },
+ limit= ,
+ stoplimit =,
+ iceberg = {
+ if (!isBBOmktdata) { #(isOHLCmktdata){
+ if( orderType == 'iceberg'){
+ stop("iceberg orders only supported for BBO data")
+ }
+ # check to see if price moved through the limit
+ if(orderQty > 0 || (orderQty < 0 && orderType == 'stoplimit') ) {
+ # buy limit, or sell stoplimit
+ 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 || (orderQty > 0 && orderType == 'stoplimit')) {
+ # sell limit or buy stoplimit
+ 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 {
+ warning('ignoring order with quantity of zero')
+ next()
+ }
+ } else if(isBBOmktdata){
+ # check side/qty
+ if(orderQty > 0){ # positive quantity 'buy'
+ if (orderType == 'stoplimit') {
+ if(orderPrice <= as.numeric(getPrice(mktdataTimestamp,prefer='ask')[,1])){
+ # mktprice moved above our stop buy price
+ txnprice = orderPrice #assume we got filled at our stop price
+ #txnprice = as.numeric(getPrice(mktdataTimestamp,prefer='ask')[,1]) #presumes unique timestamps
+ txntime = timestamp
+ } else next()
+ } else {
+ if(orderPrice >= as.numeric(getPrice(mktdataTimestamp,prefer='ask')[,1])){
+ # 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='ask')[,1]) #presumes unique timestamps
+ txntime = timestamp
+ } else next()
+ }
+ } else { # negative quantity 'sell'
+ if (orderType == 'stoplimit') {
+ if(orderPrice >= as.numeric(getPrice(mktdataTimestamp,prefer='bid')[,1])){
+ # mktprice moved below our stop sell price
+ txnprice = orderPrice #assumption is that we're filled at our stop price
+ #txnprice = as.numeric(getPrice(mktdataTimestamp,prefer='bid')[,1]) #presumes unique timestamp
+ txntime = timestamp
+ } else next()
+ } else {
+ if(orderPrice <= as.numeric(getPrice(mktdataTimestamp,prefer='bid')[,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='bid')[,1]) #presumes unique timestamp
+ txntime = timestamp
+ } else next()
+ }
+ }
+
+
+ if( orderType == 'iceberg'){
+ #we've transacted, so the old order was closed, put in a new one
+ neworder<-addOrder(portfolio=portfolio,
+ symbol=symbol,
+ timestamp=timestamp,
+ qty=orderQty,
+ price=as.numeric(getPrice(mktdataTimestamp,prefer=prefer)[,1]),
+ ordertype=orderType,
+ side=ordersubset[ii,"Order.Side"],
+ threshold=orderThreshold,
+ status="open",
+ replace=FALSE, return=TRUE,
+ ,...=..., TxnFees=txnfees)
+ if (is.null(neworders)) neworders=neworder else neworders = rbind(neworders,neworder)
[TRUNCATED]
To get the complete diff run:
svnlook diff /svnroot/blotter -r 982
More information about the Blotter-commits
mailing list