[Blotter-commits] r247 - in pkg/quantstrat: . R man
noreply at r-forge.r-project.org
noreply at r-forge.r-project.org
Tue Feb 16 23:23:11 CET 2010
Author: braverock
Date: 2010-02-16 23:23:10 +0100 (Tue, 16 Feb 2010)
New Revision: 247
Added:
pkg/quantstrat/R/traderules.R
pkg/quantstrat/man/addPosLimit.Rd
pkg/quantstrat/man/getPosLimit.Rd
pkg/quantstrat/man/osMaxPos.Rd
pkg/quantstrat/man/osNoOp.Rd
pkg/quantstrat/man/ruleSignal.Rd
Modified:
pkg/quantstrat/DESCRIPTION
pkg/quantstrat/NAMESPACE
Log:
- add trade rules and position sizing functions + docs for same
Modified: pkg/quantstrat/DESCRIPTION
===================================================================
--- pkg/quantstrat/DESCRIPTION 2010-02-15 18:38:28 UTC (rev 246)
+++ pkg/quantstrat/DESCRIPTION 2010-02-16 22:23:10 UTC (rev 247)
@@ -10,4 +10,4 @@
Description: Specify, build, and back-test quantitative financial trading and portfolio strategies
LazyLoad: yes
License: GPL-3
-Collate: 'indicators.R' 'match.names.R' 'orders.R' 'rules.R' 'signals.R' 'strategy.R'
+Collate: 'indicators.R' 'match.names.R' 'orders.R' 'rules.R' 'signals.R' 'strategy.R' 'traderules.R'
Modified: pkg/quantstrat/NAMESPACE
===================================================================
--- pkg/quantstrat/NAMESPACE 2010-02-15 18:38:28 UTC (rev 246)
+++ pkg/quantstrat/NAMESPACE 2010-02-16 22:23:10 UTC (rev 247)
@@ -20,3 +20,7 @@
export(applyStrategy)
export(is.strategy)
export(getStrategy)
+export(ruleSignal)
+export(osNoOp)
+export(addPosLimit)
+export(osMaxPos)
Added: pkg/quantstrat/R/traderules.R
===================================================================
--- pkg/quantstrat/R/traderules.R (rev 0)
+++ pkg/quantstrat/R/traderules.R 2010-02-16 22:23:10 UTC (rev 247)
@@ -0,0 +1,199 @@
+
+#' default rule to execute a trade on a signal
+#'
+#' \code{pricemethod} may be one of 'market' and 'opside' which will either try to get the price of the market at \code{timestamp} and use this as the order price
+#' @param mktdata an xts object containing market data. depending on rules, may need to be in OHLCV or BBO formats, and may include indicator and signal information
+#' @param timestamp timestamp coercible to POSIXct that will be the time the order will be inserted on
+#' @param sigcol column name to check for signal
+#' @param sigval signal value to match against
+#' @param orderqty numeric quantity of the desired order, modified by osFUN
+#' @param ordertype one of "market","limit","stoplimit", or "stoptrailing"
+#' @param orderside one of either "long" or "short"
+#' @param threshold numeric threshold to apply to trailing stop orders, default NULL
+#' @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
+#' @param osFUN function or text descriptor of function to use for order sizing, default \code{\link{osNoOp}}
+#' @param pricemethod one of 'market' or 'opside', see Details
+#' @param portfolio text name of the portfolio to place orders in
+#' @param symbol identifier of the instrument to place orders for. The name of any associated price objects (xts prices, usually OHLC) should match these
+#' @param ... any other passthru parameters
+#' @seealso \code{\link{osNoOp}}
+#' @export
+ruleSignal <- function(mktdata, timestamp, sigcol, sigval, orderqty=0, ordertype, orderside, threshold, replace=TRUE, delay=0.0001, osFUN='osNoOp', pricemethod=c('market','opside'), portfolio, symbol, ... ) {
+ if(!is.function(osFUN)) osFUN<-match.fun(osFUN)
+ if (mktdata[timestamp][,sigcol] == sigval) {
+ #TODO add fancy formals matching for osFUN
+ orderqty <- osFUN(strategy, mktdata, timestamp, orderqty, ordertype, orderside, portfolio, symbol)
+ #TODO calculate order price using pricemethod
+ switch(pricemethod,
+ opside = {}, #getPrice...
+ market = {} #getPrice...
+ )
+ if(!is.null(orderqty) & !orderqty == 0){
+ addOrder(portfolio, symbol, timestamp, orderqty, orderprice, ordertype=ordertype, side=orderside, status="open", replace=replace , delay=delay, ...)
+ }
+ }
+}
+
+#TODO ruleORSignal
+#TODO ruleANDSingnal
+
+
+#' default order sizing function
+#'
+#' default function performs no operation (NoOp), returns orderqty
+#'
+#' @param mktdata an xts object containing market data. depending on rules, may need to be in OHLCV or BBO formats, and may include indicator and signal information
+#' @param timestamp timestamp coercible to POSIXct that will be the time the order will be inserted on
+#' @param orderqty numeric quantity of the desired order, modified by osFUN
+#' @param ordertype one of "market","limit","stoplimit", or "stoptrailing"
+#' @param orderside one of either "long" or "short"
+#' @param portfolio text name of the portfolio to place orders in
+#' @param symbol identifier of the instrument to place orders for. The name of any associated price objects (xts prices, usually OHLC) should match these
+#' @export
+osNoOp <- function(mktdata, timestamp, orderqty, ordertype, orderside, portfolio, symbol){
+ return(orderqty)
+}
+
+
+#' add position and level limits at timestamp
+#'
+#' @param portfolio text name of the portfolio to place orders in
+#' @param symbol identifier of the instrument to place orders for. The name of any associated price objects (xts prices, usually OHLC) should match these
+#' @param timestamp timestamp coercible to POSIXct that will be the time the order will be inserted on
+#' @param maxpos numeric maximum long position for symbol
+#' @param longlevels numeric number of levels
+#' @param minpos numeric minimum position, default 0 (short allowed use negative number)
+#' @param shortlevels numeric number of short levels
+#' @seealso
+#' \code{\link{osMaxPos}}
+#' \code{\link{getPosLimit}}
+#' @export
+addPosLimit <- function(portfolio, symbol, timestamp, maxpos, longlevels=1, minpos=0, shortlevels=0){
+ portf<-getPortfolio(portfolio)
+ newrow <- xts(c(maxpos, longlevels, minpos, shortlevels),order.by=as.POSIXct(timestamp))
+ if(is.null(portf[[symbol]]$PosLimit)) {
+ portf[[symbol]]$PosLimit <- newrow
+ colnames(portf[[symbol]]$PosLimit)<-c("MaxPos","LongLevels","MinPos","ShortLevels")
+ } else {
+ if(!is.null(portf[[symbol]]$PosLimit[timestamp])){
+ # it exists already, so replace
+ portf[[symbol]]$PosLimit[timestamp]<-newrow
+ } else {
+ # add a new row on timestamp
+ portf[[symbol]]$PosLimit <- rbind(portf[[symbol]]$PosLimit,newrow)
+ }
+ }
+ assign(paste("portfolio",portfolio,sep='.'),portf,envir=.blotter)
+}
+
+#' get position and level limits on timestamp
+#' @param portfolio text name of the portfolio to place orders in
+#' @param symbol identifier of the instrument to place orders for. The name of any associated price objects (xts prices, usually OHLC) should match these
+#' @param timestamp timestamp coercible to POSIXct that will be the time the order will be inserted on
+getPosLimit <- function(portfolio, symbol, timestamp){
+ portf<-getPortfolio(portfolio)
+ # try to get on timestamp, otherwise find the most recent
+ toDate = paste('::', timestamp, sep="")
+ PosLimit = last(portf[[symbol]]$PosLimit[toDate])
+ return(PosLimit)
+}
+
+#' order sizing function for position limits and level sizing
+#'
+#' levels are a simplification of more complex (proprietary)
+#' techniques sometimes used for order sizing.
+#' the max orderqty returned will be the limit/levels
+#' Obviously the strategy rules could ask for smaller order sizes,
+#' but this is the default. If you don't want to use levels, set
+#' them to 1.
+#'
+#' @param mktdata an xts object containing market data. depending on rules, may need to be in OHLCV or BBO formats, and may include indicator and signal information
+#' @param timestamp timestamp coercible to POSIXct that will be the time the order will be inserted on
+#' @param orderqty numeric quantity of the desired order, modified by osFUN
+#' @param ordertype one of "market","limit","stoplimit", or "stoptrailing"
+#' @param orderside one of either "long" or "short"
+#' @param portfolio text name of the portfolio to place orders in
+#' @param symbol identifier of the instrument to place orders for. The name of any associated price objects (xts prices, usually OHLC) should match these
+#' @export
+osMaxPos <- function(mktdata, timestamp, orderqty, ordertype, orderside, portfolio, symbol){
+ # check for current position
+ pos<-getPosQty(portoflio,symbol,timestamp)
+ # check against max position
+ PosLimit<-getPosLimit(portoflio,symbol,timestamp)
+ # check levels
+
+ # buy long
+ if(orderqty>0 & orderside=='long'){
+ if ((orderqty+pos)<PosLimit[,"MaxPos"]) {
+ #we have room to expand the position
+ if(orderqty<=(PosLimit[,"MaxPos"]/PosLimit[,"LongLevels"]) ) {
+ orderqty=orderqty
+ } else {
+ orderqty = round(PosLimit[,"MaxPos"]/PosLimit[,"LongLevels"],0) #note no round lots
+ }
+ } else {
+ # this order would put us over the MaxPos limit
+ orderqty<-ifelse((PosLimit[,"MaxPos"]-pos)<=round(PosLimit[,"MaxPos"]/PosLimit[,"LongLevels"],0),PosLimit[,"MaxPos"]-pos, round(PosLimit[,"MaxPos"]/PosLimit[,"LongLevels"],0))
+ if(oderqty+pos>PosLimit[,"MaxPos"]) orderqty <- PosLimit[,"MaxPos"]-pos
+ }
+ return(orderqty)
+ }
+
+ #sell long
+ if(orderqty<0 & orderside=='long'){
+ if ((orderqty+pos)>=0) {
+ return(orderqty)
+ } else {
+ orderqty<-pos #flatten position, don't cross through zero
+ #TODO add code to break into two orders?
+ return(orderqty)
+ }
+ }
+
+ #sell short
+ if(orderqty<0 & orderside=='short'){
+ if ((orderqty+pos)>PosLimit[,"MinPos"]) {
+ #we have room to expand the position
+ if(orderqty<=(PosLimit[,"MinPos"]/PosLimit[,"ShortLevels"]) ) {
+ orderqty=orderqty
+ } else {
+ orderqty = round(PosLimit[,"MinPos"]/PosLimit[,"LongLevels"],0) #note no round lots
+ }
+ } else {
+ # this order would put us over the MinPos limit
+ orderqty<-ifelse((PosLimit[,"MinPos"]-pos)>=round(PosLimit[,"MinPos"]/PosLimit[,"ShortLevels"],0),PosLimit[,"MinPos"]-pos, round(PosLimit[,"MinPos"]/PosLimit[,"ShortLevels"],0))
+ if(oderqty+pos>PosLimit[,"MaxPos"]) orderqty <- PosLimit[,"MinPos"]-pos
+ }
+ return(orderqty)
+ }
+
+ #buy cover short
+ if(orderqty>0 & orderside=='short'){
+ if ((orderqty+pos)<=0) {
+ return(orderqty)
+ } else {
+ orderqty<-pos #flatten position, don't cross through zero
+ #TODO add code to break into two orders?
+ return(orderqty)
+ }
+ }
+
+ # fall through
+ return(0)
+}
+
+#TODO ruleRiskPosLimits to check for overfilled position and scale back
+
+###############################################################################
+# R (http://r-project.org/) Quantitative Strategy Model Framework
+#
+# Copyright (c) 2009-2010
+# Peter Carl, Dirk Eddelbuettel, Brian G. Peterson, Jeffrey Ryan, and Joshua Ulrich
+#
+# This library is distributed under the terms of the GNU Public License (GPL)
+# for full details see the file COPYING
+#
+# $Id$
+#
+###############################################################################
Property changes on: pkg/quantstrat/R/traderules.R
___________________________________________________________________
Name: svn:keywords
+ Revision Id Date Author
Added: pkg/quantstrat/man/addPosLimit.Rd
===================================================================
--- pkg/quantstrat/man/addPosLimit.Rd (rev 0)
+++ pkg/quantstrat/man/addPosLimit.Rd 2010-02-16 22:23:10 UTC (rev 247)
@@ -0,0 +1,14 @@
+\name{addPosLimit}
+\alias{addPosLimit}
+\title{add position and level limits at timestamp...}
+\usage{addPosLimit(portfolio, symbol, timestamp, maxpos, longlevels=1, minpos=0, shortlevels=0)}
+\description{add position and level limits at timestamp}
+\seealso{\code{\link{osMaxPos}}
+\code{\link{getPosLimit}}}
+\arguments{\item{portfolio}{text name of the portfolio to place orders in}
+\item{symbol}{identifier of the instrument to place orders for. The name of any associated price objects (xts prices, usually OHLC) should match these}
+\item{timestamp}{timestamp coercible to POSIXct that will be the time the order will be inserted on}
+\item{maxpos}{numeric maximum long position for symbol}
+\item{longlevels}{numeric number of levels}
+\item{minpos}{numeric minimum position, default 0 (short allowed use negative number)}
+\item{shortlevels}{numeric number of short levels}}
Property changes on: pkg/quantstrat/man/addPosLimit.Rd
___________________________________________________________________
Name: svn:keywords
+ Revision Id Date Author
Added: pkg/quantstrat/man/getPosLimit.Rd
===================================================================
--- pkg/quantstrat/man/getPosLimit.Rd (rev 0)
+++ pkg/quantstrat/man/getPosLimit.Rd 2010-02-16 22:23:10 UTC (rev 247)
@@ -0,0 +1,8 @@
+\name{getPosLimit}
+\alias{getPosLimit}
+\title{get position and level limits on timestamp...}
+\usage{getPosLimit(portfolio, symbol, timestamp)}
+\description{get position and level limits on timestamp}
+\arguments{\item{portfolio}{text name of the portfolio to place orders in}
+\item{symbol}{identifier of the instrument to place orders for. The name of any associated price objects (xts prices, usually OHLC) should match these}
+\item{timestamp}{timestamp coercible to POSIXct that will be the time the order will be inserted on}}
Property changes on: pkg/quantstrat/man/getPosLimit.Rd
___________________________________________________________________
Name: svn:keywords
+ Revision Id Date Author
Added: pkg/quantstrat/man/osMaxPos.Rd
===================================================================
--- pkg/quantstrat/man/osMaxPos.Rd (rev 0)
+++ pkg/quantstrat/man/osMaxPos.Rd 2010-02-16 22:23:10 UTC (rev 247)
@@ -0,0 +1,18 @@
+\name{osMaxPos}
+\alias{osMaxPos}
+\title{order sizing function for position limits and level sizing...}
+\usage{osMaxPos(mktdata, timestamp, orderqty, ordertype, orderside, portfolio, symbol)}
+\description{order sizing function for position limits and level sizing}
+\details{levels are a simplification of more complex (proprietary)
+techniques sometimes used for order sizing.
+the max orderqty returned will be the limit/levels
+Obviously the strategy rules could ask for smaller order sizes,
+but this is the default. If you don't want to use levels, set
+them to 1.}
+\arguments{\item{mktdata}{an xts object containing market data. depending on rules, may need to be in OHLCV or BBO formats, and may include indicator and signal information}
+\item{timestamp}{timestamp coercible to POSIXct that will be the time the order will be inserted on}
+\item{orderqty}{numeric quantity of the desired order, modified by osFUN}
+\item{ordertype}{one of "market","limit","stoplimit", or "stoptrailing"}
+\item{orderside}{one of either "long" or "short"}
+\item{portfolio}{text name of the portfolio to place orders in}
+\item{symbol}{identifier of the instrument to place orders for. The name of any associated price objects (xts prices, usually OHLC) should match these}}
Property changes on: pkg/quantstrat/man/osMaxPos.Rd
___________________________________________________________________
Name: svn:keywords
+ Revision Id Date Author
Added: pkg/quantstrat/man/osNoOp.Rd
===================================================================
--- pkg/quantstrat/man/osNoOp.Rd (rev 0)
+++ pkg/quantstrat/man/osNoOp.Rd 2010-02-16 22:23:10 UTC (rev 247)
@@ -0,0 +1,13 @@
+\name{osNoOp}
+\alias{osNoOp}
+\title{default order sizing function...}
+\usage{osNoOp(mktdata, timestamp, orderqty, ordertype, orderside, portfolio, symbol)}
+\description{default order sizing function}
+\details{default function performs no operation (NoOp), returns orderqty}
+\arguments{\item{mktdata}{an xts object containing market data. depending on rules, may need to be in OHLCV or BBO formats, and may include indicator and signal information}
+\item{timestamp}{timestamp coercible to POSIXct that will be the time the order will be inserted on}
+\item{orderqty}{numeric quantity of the desired order, modified by osFUN}
+\item{ordertype}{one of "market","limit","stoplimit", or "stoptrailing"}
+\item{orderside}{one of either "long" or "short"}
+\item{portfolio}{text name of the portfolio to place orders in}
+\item{symbol}{identifier of the instrument to place orders for. The name of any associated price objects (xts prices, usually OHLC) should match these}}
Property changes on: pkg/quantstrat/man/osNoOp.Rd
___________________________________________________________________
Name: svn:keywords
+ Revision Id Date Author
Added: pkg/quantstrat/man/ruleSignal.Rd
===================================================================
--- pkg/quantstrat/man/ruleSignal.Rd (rev 0)
+++ pkg/quantstrat/man/ruleSignal.Rd 2010-02-16 22:23:10 UTC (rev 247)
@@ -0,0 +1,23 @@
+\name{ruleSignal}
+\alias{ruleSignal}
+\title{default rule to execute a trade on a signal...}
+\usage{ruleSignal(mktdata, timestamp, sigcol, sigval, orderqty=0, ordertype, orderside, threshold, replace=TRUE, delay=1e-04, osFUN="osNoOp",
+ pricemethod=c("market", "opside"), portfolio, symbol, ...)}
+\description{default rule to execute a trade on a signal}
+\details{\code{pricemethod} may be one of 'market' and 'opside' which will either try to get the price of the market at \code{timestamp} and use this as the order price}
+\seealso{\code{\link{osNoOp}}}
+\arguments{\item{mktdata}{an xts object containing market data. depending on rules, may need to be in OHLCV or BBO formats, and may include indicator and signal information}
+\item{timestamp}{timestamp coercible to POSIXct that will be the time the order will be inserted on}
+\item{sigcol}{column name to check for signal}
+\item{sigval}{signal value to match against}
+\item{orderqty}{numeric quantity of the desired order, modified by osFUN}
+\item{ordertype}{one of "market","limit","stoplimit", or "stoptrailing"}
+\item{orderside}{one of either "long" or "short"}
+\item{threshold}{numeric threshold to apply to trailing stop orders, default NULL}
+\item{replace}{TRUE/FALSE, whether to replace any other open order(s) on this portfolio symbol, default TRUE}
+\item{delay}{what delay to add to timestamp when inserting the order into the order book, in seconds}
+\item{osFUN}{function or text descriptor of function to use for order sizing, default \code{\link{osNoOp}}}
+\item{pricemethod}{one of 'market' or 'opside', see Details}
+\item{portfolio}{text name of the portfolio to place orders in}
+\item{symbol}{identifier of the instrument to place orders for. The name of any associated price objects (xts prices, usually OHLC) should match these}
+\item{...}{any other passthru parameters}}
Property changes on: pkg/quantstrat/man/ruleSignal.Rd
___________________________________________________________________
Name: svn:keywords
+ Revision Id Date Author
More information about the Blotter-commits
mailing list