[Blotter-commits] r1206 - pkg/quantstrat/R
noreply at r-forge.r-project.org
noreply at r-forge.r-project.org
Tue Oct 2 22:39:39 CEST 2012
Author: opentrades
Date: 2012-10-02 22:39:38 +0200 (Tue, 02 Oct 2012)
New Revision: 1206
Modified:
pkg/quantstrat/R/orders.R
pkg/quantstrat/R/ruleOrderProc.R
Log:
- reversed stopenter order code
- enhanced threshold calculation in orders.R to include qty='all', as well as limit orders
Modified: pkg/quantstrat/R/orders.R
===================================================================
--- pkg/quantstrat/R/orders.R 2012-09-30 12:59:01 UTC (rev 1205)
+++ pkg/quantstrat/R/orders.R 2012-10-02 20:39:38 UTC (rev 1206)
@@ -70,7 +70,7 @@
#' @param symbol identfier of the instrument to find orders for. The name of any associated price objects (xts prices, usually OHLC) should match these
#' @param status one of "open", "closed", "canceled", or "replaced", default "open"
#' @param timespan xts-style character timespan to be the period to find orders of the given status and ordertype
-#' @param ordertype one of NULL, "market","limit","stoplimit", "stoptrailing", "stopenter", or "iceberg" default NULL
+#' @param ordertype one of NULL, "market","limit","stoplimit", "stoptrailing" or "iceberg" default NULL
#' @param side one of NULL, "long" or "short", default NULL
#' @param qtysign one of NULL, -1,0,1 ; could be useful when all qty's are reported as positive numbers and need to be identified other ways, default NULL
#' @param orderset a tag identifying the orderset
@@ -90,8 +90,8 @@
#data quality checks
if(!is.null(status) & !length(grep(status,c("open", "closed", "canceled","replaced")))==1) stop(paste("order status:",status,' must be one of "open", "closed", "canceled", or "replaced"'))
if(!is.null(ordertype)) {
- if(is.na(charmatch(ordertype,c("market","limit","stoplimit","stoptrailing","stopenter","iceberg")))){
- stop(paste("ordertype:",ordertype,' must be one of "market","limit","stoplimit", "stoptrailing", "stopenter", or "iceberg"'))
+ 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"'))
}
}
@@ -152,11 +152,8 @@
#' than growing or shrinking the threshold distance from the current market price in relation to the threshold,
#' and will result in fewer unintended consequences and more understandable behavior.
#'
-#' We have also modeled a 'stopenter' order, which will enter a position when current price + threshold is being
-#' triggered.
-#'
-#' The 'limit', 'stoplimit', 'stoptrailing', 'stopenter' and 'iceberg' order types are the only order types that make
-#' use of the order \code{threshold}. Scalar thresholds \code{tmult=FALSE} on stoplimit, stoptrailing or stopenter orders
+#' The 'limit', 'stoplimit', 'stoptrailing' and 'iceberg' order types are the only order types that make
+#' use of the order \code{threshold}. Scalar thresholds \code{tmult=FALSE} on stoplimit or stoptrailing orders
#' will be added to the current market price to set the limit price. In other worlds, a scalar threshold
#' is the difference either positive or negative from the current price when the order is entered. With a
#' stoptrailing order, the order may be moved ("replaced") frequently.
@@ -198,9 +195,9 @@
#' @param timestamp timestamp coercible to POSIXct that will be the time to search for orders before this time
#' @param qty numeric quantity of the order
#' @param price numeric price at which the order is to be inserted
-#' @param ordertype one of "market","limit","stoplimit", "stoptrailing", "stopenter", or "iceberg"
+#' @param ordertype one of "market","limit","stoplimit", "stoptrailing" or "iceberg"
#' @param side one of either "long" or "short"
-#' @param threshold numeric threshold to apply to limit, stoplimit, stoptrailing, stopenter and iceberg orders, default NULL
+#' @param threshold numeric threshold to apply to limit, stoplimit, stoptrailing and iceberg orders, default NULL
#' @param orderset set a tag identifying the orderset
#' @param status one of "open", "closed", "canceled", or "replaced", default "open"
#' @param statustimestamp timestamp of a status update, will be blank when order is initiated
@@ -252,41 +249,54 @@
#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","stopenter","iceberg")))) stop(paste("ordertype:",ordertype,' must be one of "market","limit","stoplimit","stoptrailing", "stopenter" or"iceberg"'))
- if(!is.null(threshold) & length(price)>=1 ) {
- if(length(grep(paste("^",ordertype,"$",sep=""),c("limit","stoplimit","stoptrailing","stopenter","iceberg")))==1) {
+ 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"'))
+ if(!is.null(threshold) & length(price)>=1 )
+ {
+ if(length(grep(paste("^",ordertype,"$",sep=""),c("limit","stoplimit","stoptrailing","iceberg")))==1)
+ {
#we have a threshold set on a stop* order, process it
switch(ordertype,
- limit =,
- stoplimit =,
- iceberg =,
- stoptrailing =,
- stopenter = {
- if(isTRUE(tmult))
- {
- threshold = price*threshold
- tmult=FALSE
- }
- if(!is.null(side)&& ordertype!='iceberg' && ordertype!='limit'){
- #check to make sure the order wouldn't instantly cross, reverse threshold if that's the case
- if(side=='long') {
- if(ordertype=='stopenter') {
- if(price+threshold<price) threshold=-threshold
- } else {
+ limit =,
+ iceberg =,
+ stoplimit =,
+ stoptrailing = {
+ if(isTRUE(tmult))
+ {
+ threshold = price*threshold
+ tmult=FALSE
+ }
+ if(!is.null(side))
+ {
+ switch(ordertype,
+ limit = {
+ if(qty == 'all' && side == 'long' || qty != 'all' && as.numeric(qty) < 0) # SELL
+ {
+ #this is a limit exit, so it will sell *higher* than the current market
+ if(threshold < 0) threshold = -threshold
+ }
+ else # BUY
+ {
+ #this is a limit exit, so it will buy *lower* than the current market
+ if(threshold > 0) threshold = -threshold
+ }
+ },
+ stoplimit =,
+ stoptrailing = {
+ if(qty == 'all' && side == 'long' || qty != 'all' && as.numeric(qty) < 0) # SELL
+ {
#this is a stop exit, so it will sell *lower* than the current market
- if(price+threshold>price) threshold=-threshold
+ if(threshold > 0) threshold = -threshold
}
- } else { #side=='short'
- if(ordertype=='stopenter') {
- if(price+threshold>price) threshold=-threshold
- } else {
+ else # BUY
+ {
#this is a stop exit, so it will buy *higher* than the current market
- if(price+threshold<price) threshold=-threshold
+ if(threshold < 0) threshold = -threshold
}
}
- }
- price = price+threshold
+ )
}
+ price = price+threshold
+ }
) #end type switch
} else {
stop(paste("Threshold may only be applied to a limit, stop or iceberg order type",ordertype,threshold))
@@ -389,7 +399,7 @@
#' @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) should match these
#' @param timespan xts-style character timespan to be the period to find orders of the given status and ordertype
-#' @param ordertype one of NULL, "market","limit","stoplimit","stopenter" or "stoptrailing" default NULL
+#' @param ordertype one of NULL, "market","limit","stoplimit" or "stoptrailing" default NULL
#' @param side one of NULL, "long" or "short", default NULL
#' @param qtysign one of NULL, -1,0,1 ; could be useful when all qty's are reported as positive numbers and need to be identified other ways, default NULL
#' @param orderset set a tag identifying the orderset
@@ -422,8 +432,8 @@
stop(paste("side:",side," must be one of 'long' or 'short'"))
if(!is.null(qtysign) && (qtysign != -1 && qtysign != 1 && qtysign != 0))
stop(paste("qtysign:",qtysign," must be one of NULL, -1, 0, or 1"))
- if(!is.null(ordertype) && is.na(charmatch(ordertype,c("market","limit","stoplimit","stoptrailing","stopenter","iceberg"))))
- stop(paste("ordertype:",ordertype,' must be one of "market","limit","stoplimit","stoptrailing","stopenter", or "iceberg"'))
+ if(!is.null(ordertype) && is.na(charmatch(ordertype,c("market","limit","stoplimit","stoptrailing","iceberg"))))
+ stop(paste("ordertype:",ordertype,' must be one of "market","limit","stoplimit","stoptrailing" or "iceberg"'))
if(!is.null(orderset) && newstatus=='replaced'){
#replace any outstanding orders for this orderset
ordertype=NULL
Modified: pkg/quantstrat/R/ruleOrderProc.R
===================================================================
--- pkg/quantstrat/R/ruleOrderProc.R 2012-09-30 12:59:01 UTC (rev 1205)
+++ pkg/quantstrat/R/ruleOrderProc.R 2012-10-02 20:39:38 UTC (rev 1206)
@@ -40,7 +40,7 @@
#' @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","stopenter", or "stoptrailing" default NULL
+#' @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
@@ -137,14 +137,13 @@
},
limit= ,
stoplimit =,
- stopenter =,
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 && orderType != 'stoplimit' && orderType != 'stopenter') || (orderQty < 0 && (orderType=='stoplimit' || orderType=='stopenter'))) {
+ if((orderQty > 0 && orderType != 'stoplimit') || (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))))
@@ -152,7 +151,7 @@
txnprice = orderPrice
txntime = timestamp
} else next() # price did not move through my order, should go to next order
- } else if((orderQty < 0 && orderType != 'stoplimit' && orderType != 'stopenter') || (orderQty > 0 && (orderType=='stoplimit' || orderType=='stopenter'))) {
+ } else if((orderQty < 0 && orderType != 'stoplimit') || (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))) )
@@ -167,7 +166,7 @@
} else if(isBBOmktdata){
# check side/qty
if(orderQty > 0){ # positive quantity 'buy'
- if (orderType == 'stoplimit' || orderType == 'stopenter') {
+ 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
@@ -183,7 +182,7 @@
} else next()
}
} else { # negative quantity 'sell'
- if (orderType == 'stoplimit' || orderType == 'stopenter') {
+ 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
More information about the Blotter-commits
mailing list