[Blotter-commits] r1736 - in pkg/quantstrat: R inst/tests tests
noreply at r-forge.r-project.org
noreply at r-forge.r-project.org
Fri Mar 25 21:40:30 CET 2016
Author: bodanker
Date: 2016-03-25 21:40:30 +0100 (Fri, 25 Mar 2016)
New Revision: 1736
Added:
pkg/quantstrat/inst/tests/test_osMaxPos.R
Modified:
pkg/quantstrat/R/osFUNs.R
pkg/quantstrat/tests/run-all.R
Log:
Address issues w/osMaxPos and add tests (#6306)
R-Forge issue #6306 highlights two potential issues with osMasPos. I
cannot seem to trigger any bug via tests for the first problem:
if(orderqty+pos > PosLimit[,"MaxPos"])
orderqty <- PosLimit[,"MinPos"]-pos
which seems like it should be:
if(orderqty-pos < PosLimit[,"MinPos"])
orderqty <- PosLimit[,"MinPos"]+pos
The second error is most certainly a problem:
orderqty <- pos #flatten position, don't cross through zero
should be
orderqty <- -pos #flatten position, don't cross through zero
because we are buying to cover a short position.
Move the ruletype == "risk" and orderqty == "all" checks to the
beginning of the function, so we can throw an error for unsupported
combinations.
Replace "&" with "&&" inside if statements, so we get the benefit
of short-circuiting when the first isn't TRUE. This helps handle
orderside = NULL more gracefully.
Use as.integer(orderqty) to strip attributes (e.g. dim, xts stuff, etc)
that come from the position limit object when we are at position limits.
Add unit tests!
Modified: pkg/quantstrat/R/osFUNs.R
===================================================================
--- pkg/quantstrat/R/osFUNs.R 2016-03-25 17:55:39 UTC (rev 1735)
+++ pkg/quantstrat/R/osFUNs.R 2016-03-25 20:40:30 UTC (rev 1736)
@@ -145,9 +145,16 @@
stop(paste('no position limit defined for portfolio', portfolio))
#TODO add handling for orderqty='all', and handle risk ruletype separately
+ if(is.character(orderqty)) {
+ if(ruletype == "risk" && orderqty == "all") {
+ orderqty <- pos * -1
+ } else {
+ stop("orderqty ", orderqty, " is not supported for non-risk ruletypes")
+ }
+ }
#check order side
- if(is.null(orderside) & !isTRUE(orderqty == 0)){
+ if(is.null(orderside) && !isTRUE(orderqty == 0)) {
curqty<-pos
if (curqty>0 ){
#we have a long position
@@ -166,7 +173,7 @@
# check levels
# buy long
- if(orderqty>0 & orderside=='long'){
+ if(orderqty>0 && orderside=='long') {
if ((orderqty+pos)<PosLimit[,"MaxPos"]) {
#we have room to expand the position
if(orderqty<=(PosLimit[,"MaxPos"]/PosLimit[,"LongLevels"]) ) {
@@ -179,14 +186,13 @@
orderqty<-ifelse((PosLimit[,"MaxPos"]-pos)<=round(PosLimit[,"MaxPos"]/PosLimit[,"LongLevels"],0),PosLimit[,"MaxPos"]-pos, round(PosLimit[,"MaxPos"]/PosLimit[,"LongLevels"],0))
if(orderqty+pos>PosLimit[,"MaxPos"]) orderqty <- PosLimit[,"MaxPos"]-pos
}
- return(orderqty)
+ return(as.integer(orderqty))
}
#sell long
- if(orderqty<0 & orderside=='long'){
+ if(orderqty<0 && orderside=='long') {
if(ruletype=='risk'){
- if(orderqty=='all') return(-1*pos)
- else return(orderqty)
+ return(orderqty)
}
if ((orderqty+pos)>=0) {
return(orderqty)
@@ -198,7 +204,7 @@
}
#sell short
- if(orderqty<0 & orderside=='short'){
+ if(orderqty<0 && orderside=='short') {
if ((orderqty+pos)>PosLimit[,"MinPos"]) {
#we have room to expand the position
if(orderqty>=(PosLimit[,"MinPos"]/PosLimit[,"ShortLevels"]) ) {
@@ -211,19 +217,18 @@
orderqty<-ifelse((PosLimit[,"MinPos"]-pos)>=round(PosLimit[,"MinPos"]/PosLimit[,"ShortLevels"],0),PosLimit[,"MinPos"]-pos, round(PosLimit[,"MinPos"]/PosLimit[,"ShortLevels"],0))
if(orderqty+pos>PosLimit[,"MaxPos"]) orderqty <- PosLimit[,"MinPos"]-pos
}
- return(orderqty)
+ return(as.integer(orderqty))
}
#buy cover short
- if(orderqty>0 & orderside=='short'){
+ if(orderqty>0 && orderside=='short') {
if(ruletype=='risk'){
- if(orderqty=='all') return(-1*pos)
- else return(orderqty)
+ return(orderqty)
}
if ((orderqty+pos)<=0) {
return(orderqty)
} else {
- orderqty<-pos #flatten position, don't cross through zero
+ orderqty <- -pos #flatten position, don't cross through zero
#TODO add code to break into two orders?
return(orderqty)
}
Added: pkg/quantstrat/inst/tests/test_osMaxPos.R
===================================================================
--- pkg/quantstrat/inst/tests/test_osMaxPos.R (rev 0)
+++ pkg/quantstrat/inst/tests/test_osMaxPos.R 2016-03-25 20:40:30 UTC (rev 1736)
@@ -0,0 +1,167 @@
+stopifnot(require(testthat))
+stopifnot(require(quantstrat))
+context("osMaxPos")
+
+# setup
+symbol <- "test"
+portfolio <- "test_osMaxPos"
+initPortf(portfolio, symbol, -3000)
+
+addPosLimit(portfolio, symbol, "2013-09-01", 8000, 8, -4000, 4)
+timestamp <- as.Date("2013-09-09")
+
+###############################################################################
+# short position, ruletype == "risk"
+test_that("risk-flatten short w/orderqty = 'all'", {
+ qty <- osMaxPos(NULL, timestamp, "all", "", "short", portfolio, symbol, "risk")
+ expect_equal(qty, 3000)
+ qty <- osMaxPos(NULL, timestamp, "all", "", NULL, portfolio, symbol, "risk")
+ expect_equal(qty, 3000)
+})
+
+# FIXME: Should risk be able to take position across zero?
+test_that("risk-flatten short w/orderqty > abs(position)", {
+ qty <- osMaxPos(NULL, timestamp, 4000, "", "short", portfolio, symbol, "risk")
+ expect_equal(qty, 4000)
+ qty <- osMaxPos(NULL, timestamp, 4000, "", NULL, portfolio, symbol, "risk")
+ expect_equal(qty, 4000)
+})
+
+test_that("risk-reduce short", {
+ qty <- osMaxPos(NULL, timestamp, 2000, "", "short", portfolio, symbol, "risk")
+ expect_equal(qty, 2000)
+ qty <- osMaxPos(NULL, timestamp, 2000, "", NULL, portfolio, symbol, "risk")
+ expect_equal(qty, 2000)
+})
+
+# FIXME: What should these do? Risk rules probably shouldn't be able to increase position
+#test_that("risk-increase short within limits", {
+# qty <- osMaxPos(NULL, timestamp, -1000, "", "short", portfolio, symbol, "risk")
+# qty <- osMaxPos(NULL, timestamp, -1000, "", NULL, portfolio, symbol, "risk")
+#})
+#
+#test_that("risk-increase short beyond limits", {
+# qty <- osMaxPos(NULL, timestamp, -2000, "", "short", portfolio, symbol, "risk")
+# qty <- osMaxPos(NULL, timestamp, -2000, "", NULL, portfolio, symbol, "risk")
+#})
+
+###############################################################################
+# short position, ruletype != "risk"
+test_that("flatten short w/orderqty = 'all'", {
+ # ordertype="all" is not currently supported for non-risk ruletypes
+ expect_error(osMaxPos(NULL, timestamp, "all", "", "short", portfolio, symbol, ""))
+})
+
+test_that("flatten short w/orderqty > abs(position)", {
+ qty <- osMaxPos(NULL, timestamp, 4000, "", "short", portfolio, symbol, "")
+ expect_equal(qty, 3000)
+ qty <- osMaxPos(NULL, timestamp, 4000, "", NULL, portfolio, symbol, "")
+ expect_equal(qty, 3000)
+})
+
+test_that("reduce short", {
+ qty <- osMaxPos(NULL, timestamp, 2000, "", "short", portfolio, symbol, "")
+ expect_equal(qty, 2000)
+ qty <- osMaxPos(NULL, timestamp, 2000, "", NULL, portfolio, symbol, "")
+ expect_equal(qty, 2000)
+})
+
+test_that("increase short within limits", {
+ qty <- osMaxPos(NULL, timestamp, -1000, "", "short", portfolio, symbol, "risk")
+ expect_equal(qty, -1000)
+ qty <- osMaxPos(NULL, timestamp, -1000, "", NULL, portfolio, symbol, "risk")
+ expect_equal(qty, -1000)
+})
+
+test_that("increase short beyond limits", {
+ qty <- osMaxPos(NULL, timestamp, -2000, "", "short", portfolio, symbol, "risk")
+ expect_equal(qty, -1000)
+ qty <- osMaxPos(NULL, timestamp, -2000, "", NULL, portfolio, symbol, "risk")
+ expect_equal(qty, -1000)
+})
+
+# add transaction to make portfolio long
+suppressWarnings(addTxn(portfolio, symbol, timestamp-1L, 10000, 1, verbose=FALSE))
+
+###############################################################################
+# long position, ruletype == "risk"
+test_that("risk-flatten long w/orderqty = 'all'", {
+ qty <- osMaxPos(NULL, timestamp, "all", "", "long", portfolio, symbol, "risk")
+ expect_equal(qty, -7000)
+ qty <- osMaxPos(NULL, timestamp, "all", "", NULL, portfolio, symbol, "risk")
+ expect_equal(qty, -7000)
+})
+
+test_that("risk-reduce long", {
+ qty <- osMaxPos(NULL, timestamp, -2000, "", "long", portfolio, symbol, "risk")
+ expect_equal(qty, -2000)
+ qty <- osMaxPos(NULL, timestamp, -2000, "", NULL, portfolio, symbol, "risk")
+ expect_equal(qty, -2000)
+})
+
+# FIXME: Should risk be able to take position across zero?
+test_that("risk-flatten long w/orderqty > abs(position)", {
+ qty <- osMaxPos(NULL, timestamp, -8000, "", "long", portfolio, symbol, "risk")
+ expect_equal(qty, -8000)
+ qty <- osMaxPos(NULL, timestamp, -8000, "", NULL, portfolio, symbol, "risk")
+ expect_equal(qty, -8000)
+})
+
+# FIXME: What should these do? Risk rules probably shouldn't be able to increase position
+#test_that("risk-increase long within limits", {
+# qty <- osMaxPos(NULL, timestamp, 1000, "", "long", portfolio, symbol, "risk")
+# qty <- osMaxPos(NULL, timestamp, 1000, "", NULL, portfolio, symbol, "risk")
+#})
+#
+#test_that("risk-increase long beyond limits", {
+# qty <- osMaxPos(NULL, timestamp, 2000, "", "long", portfolio, symbol, "risk")
+# qty <- osMaxPos(NULL, timestamp, 2000, "", NULL, portfolio, symbol, "risk")
+#})
+
+###############################################################################
+# long position, ruletype != "risk"
+test_that("flatten long w/orderqty = 'all'", {
+ # ordertype="all" is not currently supported for non-risk ruletypes
+ expect_error(osMaxPos(NULL, timestamp, "all", "", "short", portfolio, symbol, ""))
+})
+
+test_that("reduce long", {
+ qty <- osMaxPos(NULL, timestamp, -2000, "", "long", portfolio, symbol, "")
+ expect_equal(qty, -2000)
+ qty <- osMaxPos(NULL, timestamp, -2000, "", NULL, portfolio, symbol, "")
+ expect_equal(qty, -2000)
+})
+
+test_that("flatten long w/orderqty > abs(position)", {
+ qty <- osMaxPos(NULL, timestamp, -8000, "", "long", portfolio, symbol, "")
+ expect_equal(qty, -7000)
+ qty <- osMaxPos(NULL, timestamp, -8000, "", NULL, portfolio, symbol, "")
+ expect_equal(qty, -7000)
+})
+
+test_that("increase long within limits", {
+ qty <- osMaxPos(NULL, timestamp, 1000, "", "long", portfolio, symbol, "risk")
+ expect_equal(qty, 1000)
+ qty <- osMaxPos(NULL, timestamp, 1000, "", NULL, portfolio, symbol, "risk")
+ expect_equal(qty, 1000)
+})
+
+test_that("increase long beyond limits", {
+ qty <- osMaxPos(NULL, timestamp, 2000, "", "long", portfolio, symbol, "risk")
+ expect_equal(qty, 1000)
+ qty <- osMaxPos(NULL, timestamp, 2000, "", NULL, portfolio, symbol, "risk")
+ expect_equal(qty, 1000)
+})
+
+###############################################################################
+test_that("zero order quantity", {
+ qty <- osMaxPos(NULL, timestamp, 0, "", "long", portfolio, symbol, "")
+ expect_equal(qty, 0)
+ qty <- osMaxPos(NULL, timestamp, 0, "", NULL, portfolio, symbol, "")
+ expect_equal(qty, 0)
+ qty <- osMaxPos(NULL, timestamp, 0, "", "short", portfolio, symbol, "")
+ expect_equal(qty, 0)
+ qty <- osMaxPos(NULL, timestamp, 0, "", NULL, portfolio, symbol, "")
+ expect_equal(qty, 0)
+})
+
Modified: pkg/quantstrat/tests/run-all.R
===================================================================
--- pkg/quantstrat/tests/run-all.R 2016-03-25 17:55:39 UTC (rev 1735)
+++ pkg/quantstrat/tests/run-all.R 2016-03-25 20:40:30 UTC (rev 1736)
@@ -1,5 +1,6 @@
require(testthat)
require(quantstrat)
-try(test_package("quantstrat", filter="paramsets"))
+test_package("quantstrat", filter="paramsets")
+test_package("quantstrat", filter="osMaxPos")
More information about the Blotter-commits
mailing list