From noreply at r-forge.r-project.org Sun Mar 6 21:04:46 2016 From: noreply at r-forge.r-project.org (noreply at r-forge.r-project.org) Date: Sun, 6 Mar 2016 21:04:46 +0100 (CET) Subject: [Blotter-commits] r1733 - pkg/quantstrat/demo Message-ID: <20160306200446.9B39F187C2B@r-forge.r-project.org> Author: bodanker Date: 2016-03-06 21:04:46 +0100 (Sun, 06 Mar 2016) New Revision: 1733 Modified: pkg/quantstrat/demo/luxor.sample.tradeGraphs.sma.R Log: Fix typo in file name (fixes #6292) Modified: pkg/quantstrat/demo/luxor.sample.tradeGraphs.sma.R =================================================================== --- pkg/quantstrat/demo/luxor.sample.tradeGraphs.sma.R 2016-01-16 14:48:02 UTC (rev 1732) +++ pkg/quantstrat/demo/luxor.sample.tradeGraphs.sma.R 2016-03-06 20:04:46 UTC (rev 1733) @@ -15,7 +15,7 @@ load(paste0( path.package('quantstrat'), - '/data/luxor.parameters.2-10.30-55.RData') + '/data/luxor.parameters.1-10.30-55.RData') ) ### show trade graphs from stats From noreply at r-forge.r-project.org Fri Mar 11 17:31:39 2016 From: noreply at r-forge.r-project.org (noreply at r-forge.r-project.org) Date: Fri, 11 Mar 2016 17:31:39 +0100 (CET) Subject: [Blotter-commits] r1734 - pkg/quantstrat/demo Message-ID: <20160311163139.59CB4187FBD@r-forge.r-project.org> Author: bodanker Date: 2016-03-11 17:31:38 +0100 (Fri, 11 Mar 2016) New Revision: 1734 Modified: pkg/quantstrat/demo/faber.R pkg/quantstrat/demo/faber_rebal.R pkg/quantstrat/demo/luxor.1.strategy.basic.R pkg/quantstrat/demo/luxor.6.paramset.stoploss.R pkg/quantstrat/demo/luxor.6.paramset.stoptrailing.R pkg/quantstrat/demo/luxor.6.paramset.takeprofit.R pkg/quantstrat/demo/luxor.7.exit.and.risk.R Log: Replace calls to View with print in demos As of R-3.2.3, calling View() on an xts object with duplicate index values fails. This is because the data.frame will have duplicate row names and the format.data.frame method no longer appears to support it. Modified: pkg/quantstrat/demo/faber.R =================================================================== --- pkg/quantstrat/demo/faber.R 2016-03-06 20:04:46 UTC (rev 1733) +++ pkg/quantstrat/demo/faber.R 2016-03-11 16:31:38 UTC (rev 1734) @@ -137,7 +137,7 @@ ret1 <- PortfReturns('faber') ret1$total <- rowSums(ret1) -View(ret1) +print(ret1) if("package:PerformanceAnalytics" %in% search() || require("PerformanceAnalytics",quietly=TRUE)){ getSymbols("SPY", src='yahoo', index.class=c("POSIXt","POSIXct"), from='1999-01-01') @@ -148,7 +148,7 @@ } faber.stats<-tradeStats('faber')[,c('Net.Trading.PL','Max.Drawdown','Num.Trades','Profit.Factor','Std.Dev.Trade.PL','Largest.Winner','Largest.Loser','Max.Equity','Min.Equity')] -View(faber.stats) +print(faber.stats) Sys.setenv(TZ=oldtz) ############################################################################### Modified: pkg/quantstrat/demo/faber_rebal.R =================================================================== --- pkg/quantstrat/demo/faber_rebal.R 2016-03-06 20:04:46 UTC (rev 1733) +++ pkg/quantstrat/demo/faber_rebal.R 2016-03-11 16:31:38 UTC (rev 1734) @@ -156,7 +156,7 @@ ret1 <- PortfReturns('faber') ret1$total <- rowSums(ret1) -View(ret1) +print(ret1) if("package:PerformanceAnalytics" %in% search() || require("PerformanceAnalytics",quietly=TRUE)){ getSymbols("SPY", src='yahoo', index.class=c("POSIXt","POSIXct"), from='1999-01-01') Modified: pkg/quantstrat/demo/luxor.1.strategy.basic.R =================================================================== --- pkg/quantstrat/demo/luxor.1.strategy.basic.R 2016-03-06 20:04:46 UTC (rev 1733) +++ pkg/quantstrat/demo/luxor.1.strategy.basic.R 2016-03-11 16:31:38 UTC (rev 1734) @@ -117,7 +117,7 @@ applyStrategy(strategy.st, portfolio.st) -View(getOrderBook(portfolio.st)[[portfolio.st]]$GBPUSD) +print(getOrderBook(portfolio.st)[[portfolio.st]]$GBPUSD) ############################################################################### @@ -127,7 +127,7 @@ ############################################################################### -View(t(tradeStats(portfolio.st, 'GBPUSD'))) +print(t(tradeStats(portfolio.st, 'GBPUSD'))) ############################################################################### Modified: pkg/quantstrat/demo/luxor.6.paramset.stoploss.R =================================================================== --- pkg/quantstrat/demo/luxor.6.paramset.stoploss.R 2016-03-06 20:04:46 UTC (rev 1733) +++ pkg/quantstrat/demo/luxor.6.paramset.stoploss.R 2016-03-11 16:31:38 UTC (rev 1734) @@ -58,6 +58,6 @@ stats <- results$tradeStats -View(t(stats)) +print(t(stats)) plot(100*stats$StopLossLONG, stats$Net.Trading.PL, type='b', xlab='Stoploss %', ylab='Net.Trading.PL', main='Luxor') Modified: pkg/quantstrat/demo/luxor.6.paramset.stoptrailing.R =================================================================== --- pkg/quantstrat/demo/luxor.6.paramset.stoptrailing.R 2016-03-06 20:04:46 UTC (rev 1733) +++ pkg/quantstrat/demo/luxor.6.paramset.stoptrailing.R 2016-03-11 16:31:38 UTC (rev 1734) @@ -58,6 +58,6 @@ stats <- results$tradeStats -View(t(stats)) +print(t(stats)) plot(100*stats$StopTrailingLONG, stats$Net.Trading.PL, type='b', xlab='StopTrailing %', ylab='Net.Trading.PL', main='Luxor') Modified: pkg/quantstrat/demo/luxor.6.paramset.takeprofit.R =================================================================== --- pkg/quantstrat/demo/luxor.6.paramset.takeprofit.R 2016-03-06 20:04:46 UTC (rev 1733) +++ pkg/quantstrat/demo/luxor.6.paramset.takeprofit.R 2016-03-11 16:31:38 UTC (rev 1734) @@ -58,6 +58,6 @@ stats <- results$tradeStats -View(t(stats)) +print(t(stats)) plot(100*stats$TakeProfitLONG, stats$Net.Trading.PL, type='b', xlab='TakeProfit %', ylab='Net.Trading.PL', main='Luxor') Modified: pkg/quantstrat/demo/luxor.7.exit.and.risk.R =================================================================== --- pkg/quantstrat/demo/luxor.7.exit.and.risk.R 2016-03-06 20:04:46 UTC (rev 1733) +++ pkg/quantstrat/demo/luxor.7.exit.and.risk.R 2016-03-11 16:31:38 UTC (rev 1734) @@ -41,7 +41,7 @@ applyStrategy(strategy.st, portfolio.st, prefer='Open') -View(getOrderBook(portfolio.st)[[portfolio.st]]$GBPUSD) +print(getOrderBook(portfolio.st)[[portfolio.st]]$GBPUSD) ############################################################################### @@ -51,7 +51,7 @@ ############################################################################### -View(t(tradeStats(portfolio.st, 'GBPUSD'))) +print(t(tradeStats(portfolio.st, 'GBPUSD'))) ############################################################################### From noreply at r-forge.r-project.org Fri Mar 25 18:55:40 2016 From: noreply at r-forge.r-project.org (noreply at r-forge.r-project.org) Date: Fri, 25 Mar 2016 18:55:40 +0100 (CET) Subject: [Blotter-commits] r1735 - in pkg/quantstrat: . data Message-ID: <20160325175540.18FF5187E59@r-forge.r-project.org> Author: bodanker Date: 2016-03-25 18:55:39 +0100 (Fri, 25 Mar 2016) New Revision: 1735 Modified: pkg/quantstrat/DESCRIPTION pkg/quantstrat/data/luxor-p066.RData pkg/quantstrat/data/luxor.parameters.1-10.30-55.RData pkg/quantstrat/data/luxor.timespan.24x24.2002-2008.RData pkg/quantstrat/data/luxor.wfa.ples.RData Log: Compress and re-save data to appease R CMD check This is mainly so R CMD check runs faster. This also requires R >= 2.10, which is many years old and is therefore not a significant issue. Modified: pkg/quantstrat/DESCRIPTION =================================================================== --- pkg/quantstrat/DESCRIPTION 2016-03-11 16:31:38 UTC (rev 1734) +++ pkg/quantstrat/DESCRIPTION 2016-03-25 17:55:39 UTC (rev 1735) @@ -5,6 +5,7 @@ Date: $Date$ Author: Peter Carl, Brian G. Peterson, Joshua Ulrich, Jan Humme Depends: + R(>= 2.10), quantmod, xts(>= 0.8-2), blotter(>= 0.9), Modified: pkg/quantstrat/data/luxor-p066.RData =================================================================== (Binary files differ) Modified: pkg/quantstrat/data/luxor.parameters.1-10.30-55.RData =================================================================== (Binary files differ) Modified: pkg/quantstrat/data/luxor.timespan.24x24.2002-2008.RData =================================================================== (Binary files differ) Modified: pkg/quantstrat/data/luxor.wfa.ples.RData =================================================================== (Binary files differ) From noreply at r-forge.r-project.org Fri Mar 25 21:40:30 2016 From: noreply at r-forge.r-project.org (noreply at r-forge.r-project.org) Date: Fri, 25 Mar 2016 21:40:30 +0100 (CET) Subject: [Blotter-commits] r1736 - in pkg/quantstrat: R inst/tests tests Message-ID: <20160325204031.0C1C11878D1@r-forge.r-project.org> 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"]) 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") From noreply at r-forge.r-project.org Sat Mar 26 01:42:05 2016 From: noreply at r-forge.r-project.org (noreply at r-forge.r-project.org) Date: Sat, 26 Mar 2016 01:42:05 +0100 (CET) Subject: [Blotter-commits] r1737 - pkg/quantstrat/inst/tests Message-ID: <20160326004205.4EDEE18776B@r-forge.r-project.org> Author: bodanker Date: 2016-03-26 01:42:04 +0100 (Sat, 26 Mar 2016) New Revision: 1737 Modified: pkg/quantstrat/inst/tests/test_osMaxPos.R Log: Set ruletype="" for non-risk tests Copy/paste error resulted in ruletype="risk" for tests that were supposed to tests non-risk ruletypes. Modified: pkg/quantstrat/inst/tests/test_osMaxPos.R =================================================================== --- pkg/quantstrat/inst/tests/test_osMaxPos.R 2016-03-25 20:40:30 UTC (rev 1736) +++ pkg/quantstrat/inst/tests/test_osMaxPos.R 2016-03-26 00:42:04 UTC (rev 1737) @@ -67,16 +67,16 @@ }) test_that("increase short within limits", { - qty <- osMaxPos(NULL, timestamp, -1000, "", "short", portfolio, symbol, "risk") + qty <- osMaxPos(NULL, timestamp, -1000, "", "short", portfolio, symbol, "") expect_equal(qty, -1000) - qty <- osMaxPos(NULL, timestamp, -1000, "", NULL, portfolio, symbol, "risk") + qty <- osMaxPos(NULL, timestamp, -1000, "", NULL, portfolio, symbol, "") expect_equal(qty, -1000) }) test_that("increase short beyond limits", { - qty <- osMaxPos(NULL, timestamp, -2000, "", "short", portfolio, symbol, "risk") + qty <- osMaxPos(NULL, timestamp, -2000, "", "short", portfolio, symbol, "") expect_equal(qty, -1000) - qty <- osMaxPos(NULL, timestamp, -2000, "", NULL, portfolio, symbol, "risk") + qty <- osMaxPos(NULL, timestamp, -2000, "", NULL, portfolio, symbol, "") expect_equal(qty, -1000) }) @@ -140,16 +140,16 @@ }) test_that("increase long within limits", { - qty <- osMaxPos(NULL, timestamp, 1000, "", "long", portfolio, symbol, "risk") + qty <- osMaxPos(NULL, timestamp, 1000, "", "long", portfolio, symbol, "") expect_equal(qty, 1000) - qty <- osMaxPos(NULL, timestamp, 1000, "", NULL, portfolio, symbol, "risk") + qty <- osMaxPos(NULL, timestamp, 1000, "", NULL, portfolio, symbol, "") expect_equal(qty, 1000) }) test_that("increase long beyond limits", { - qty <- osMaxPos(NULL, timestamp, 2000, "", "long", portfolio, symbol, "risk") + qty <- osMaxPos(NULL, timestamp, 2000, "", "long", portfolio, symbol, "") expect_equal(qty, 1000) - qty <- osMaxPos(NULL, timestamp, 2000, "", NULL, portfolio, symbol, "risk") + qty <- osMaxPos(NULL, timestamp, 2000, "", NULL, portfolio, symbol, "") expect_equal(qty, 1000) }) From noreply at r-forge.r-project.org Sat Mar 26 15:35:14 2016 From: noreply at r-forge.r-project.org (noreply at r-forge.r-project.org) Date: Sat, 26 Mar 2016 15:35:14 +0100 (CET) Subject: [Blotter-commits] r1738 - in pkg/quantstrat: R inst/tests Message-ID: <20160326143514.59B64187765@r-forge.r-project.org> Author: bodanker Date: 2016-03-26 15:35:13 +0100 (Sat, 26 Mar 2016) New Revision: 1738 Modified: pkg/quantstrat/R/osFUNs.R pkg/quantstrat/inst/tests/test_osMaxPos.R Log: Refactor osMaxPos Attempt to simplify function logic to make it easier to reason about. Use as.numeric instead of as.integer to strip attributes because some instruments allow fractional shares (e.g. mutual funds, foreign exchange). Thanks to Brian for the correction. Add tests for max clip size check. Refactor tests so they're easier to change if we need to update them. It should also help avoid copy/paste errors (e.g. the "flatten long w/orderqty = 'all'" test under "long position, ruletype != 'risk'" incorrectly used orderside="short" instead of orderside="long"). Modified: pkg/quantstrat/R/osFUNs.R =================================================================== --- pkg/quantstrat/R/osFUNs.R 2016-03-26 00:42:04 UTC (rev 1737) +++ pkg/quantstrat/R/osFUNs.R 2016-03-26 14:35:13 UTC (rev 1738) @@ -170,34 +170,31 @@ orderside<-'short' } } + # TODO: need to ensure that orderside and pos align if orderside != NULL? + # i.e. it's possible user passes orderside = "long" when pos < 0. # check levels # buy long if(orderqty>0 && orderside=='long') { - if ((orderqty+pos)PosLimit[,"MaxPos"]) orderqty <- PosLimit[,"MaxPos"]-pos + # note no round lots for max clip + clip <- round(PosLimit[,"MaxPos"] / PosLimit[,"LongLevels"], 0) + + if ((orderqty+pos) > PosLimit[,"MaxPos"]) { + # this order would put us beyond the MaxPos limit + orderqty <- PosLimit[,"MaxPos"] - pos } - return(as.integer(orderqty)) + # check clip size + orderqty <- min(orderqty, clip) + + return(as.numeric(orderqty)) # strip attributes } #sell long if(orderqty<0 && orderside=='long') { - if(ruletype=='risk'){ - return(orderqty) - } - if ((orderqty+pos)>=0) { + if(ruletype=='risk' || (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) } @@ -205,28 +202,23 @@ #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[,"ShortLevels"],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(orderqty+pos>PosLimit[,"MaxPos"]) orderqty <- PosLimit[,"MinPos"]-pos + # note no round lots for max clip + clip <- round(PosLimit[,"MinPos"] / PosLimit[,"ShortLevels"], 0) + + if ((orderqty+pos) < PosLimit[,"MinPos"]) { + # this order would put us beyond the MinPos limit + orderqty <- PosLimit[,"MinPos"] - pos } - return(as.integer(orderqty)) + # check clip size + orderqty <- max(orderqty, clip) + + return(as.numeric(orderqty)) # strip attributes } #buy cover short if(orderqty>0 && orderside=='short') { - if(ruletype=='risk'){ + if(ruletype=='risk' || (orderqty+pos)<=0) { return(orderqty) - } - if ((orderqty+pos)<=0) { - return(orderqty) } else { orderqty <- -pos #flatten position, don't cross through zero #TODO add code to break into two orders? Modified: pkg/quantstrat/inst/tests/test_osMaxPos.R =================================================================== --- pkg/quantstrat/inst/tests/test_osMaxPos.R 2016-03-26 00:42:04 UTC (rev 1737) +++ pkg/quantstrat/inst/tests/test_osMaxPos.R 2016-03-26 14:35:13 UTC (rev 1738) @@ -5,151 +5,180 @@ # setup symbol <- "test" portfolio <- "test_osMaxPos" -initPortf(portfolio, symbol, -3000) +longPos <- 6000 +shortPos <- -2000 +initPortf(portfolio, symbol, shortPos) addPosLimit(portfolio, symbol, "2013-09-01", 8000, 8, -4000, 4) timestamp <- as.Date("2013-09-09") ############################################################################### # short position, ruletype == "risk" +side <- "short" +type <- "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) + qty <- osMaxPos(NULL, timestamp, "all", "", side, portfolio, symbol, type) + expect_equal(qty, -shortPos) + qty <- osMaxPos(NULL, timestamp, "all", "", NULL, portfolio, symbol, type) + expect_equal(qty, -shortPos) }) # 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) + qty <- osMaxPos(NULL, timestamp, -shortPos*2, "", side, portfolio, symbol, type) + expect_equal(qty, -shortPos*2) + qty <- osMaxPos(NULL, timestamp, -shortPos*2, "", NULL, portfolio, symbol, type) + expect_equal(qty, -shortPos*2) }) test_that("risk-reduce short", { - qty <- osMaxPos(NULL, timestamp, 2000, "", "short", portfolio, symbol, "risk") + qty <- osMaxPos(NULL, timestamp, 2000, "", side, portfolio, symbol, type) expect_equal(qty, 2000) - qty <- osMaxPos(NULL, timestamp, 2000, "", NULL, portfolio, symbol, "risk") + qty <- osMaxPos(NULL, timestamp, 2000, "", NULL, portfolio, symbol, type) 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") +# qty <- osMaxPos(NULL, timestamp, -1000, "", side, portfolio, symbol, type) +# qty <- osMaxPos(NULL, timestamp, -1000, "", NULL, portfolio, symbol, type) #}) # #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") +# qty <- osMaxPos(NULL, timestamp, -2000, "", side, portfolio, symbol, type) +# qty <- osMaxPos(NULL, timestamp, -2000, "", NULL, portfolio, symbol, type) #}) ############################################################################### # short position, ruletype != "risk" +type <- "" + 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, "")) + expect_error(osMaxPos(NULL, timestamp, "all", "", side, portfolio, symbol, type)) }) 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) + qty <- osMaxPos(NULL, timestamp, -shortPos*2, "", side, portfolio, symbol, type) + expect_equal(qty, -shortPos) + qty <- osMaxPos(NULL, timestamp, -shortPos*2, "", NULL, portfolio, symbol, type) + expect_equal(qty, -shortPos) }) test_that("reduce short", { - qty <- osMaxPos(NULL, timestamp, 2000, "", "short", portfolio, symbol, "") + qty <- osMaxPos(NULL, timestamp, 2000, "", side, portfolio, symbol, type) expect_equal(qty, 2000) - qty <- osMaxPos(NULL, timestamp, 2000, "", NULL, portfolio, symbol, "") + qty <- osMaxPos(NULL, timestamp, 2000, "", NULL, portfolio, symbol, type) expect_equal(qty, 2000) }) -test_that("increase short within limits", { - qty <- osMaxPos(NULL, timestamp, -1000, "", "short", portfolio, symbol, "") +test_that("increase short within limits, < clip size", { + qty <- osMaxPos(NULL, timestamp, -1000, "", side, portfolio, symbol, type) expect_equal(qty, -1000) - qty <- osMaxPos(NULL, timestamp, -1000, "", NULL, portfolio, symbol, "") + qty <- osMaxPos(NULL, timestamp, -1000, "", NULL, portfolio, symbol, type) expect_equal(qty, -1000) }) +test_that("increase short within limits, > clip size", { + qty <- osMaxPos(NULL, timestamp, -1500, "", side, portfolio, symbol, type) + expect_equal(qty, -1000) + qty <- osMaxPos(NULL, timestamp, -1500, "", NULL, portfolio, symbol, type) + expect_equal(qty, -1000) +}) + test_that("increase short beyond limits", { - qty <- osMaxPos(NULL, timestamp, -2000, "", "short", portfolio, symbol, "") + qty <- osMaxPos(NULL, timestamp, -2000, "", side, portfolio, symbol, type) expect_equal(qty, -1000) - qty <- osMaxPos(NULL, timestamp, -2000, "", NULL, portfolio, symbol, "") + qty <- osMaxPos(NULL, timestamp, -2000, "", NULL, portfolio, symbol, type) expect_equal(qty, -1000) }) -# add transaction to make portfolio long -suppressWarnings(addTxn(portfolio, symbol, timestamp-1L, 10000, 1, verbose=FALSE)) +# add transactions to make portfolio long +suppressWarnings({ + addTxn(portfolio, symbol, timestamp-2L, -shortPos, 1, verbose=FALSE) + addTxn(portfolio, symbol, timestamp-1L, longPos, 1, verbose=FALSE) +}) ############################################################################### # long position, ruletype == "risk" +side <- "long" +type <- "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) + qty <- osMaxPos(NULL, timestamp, "all", "", side, portfolio, symbol, type) + expect_equal(qty, -longPos) + qty <- osMaxPos(NULL, timestamp, "all", "", NULL, portfolio, symbol, type) + expect_equal(qty, -longPos) }) test_that("risk-reduce long", { - qty <- osMaxPos(NULL, timestamp, -2000, "", "long", portfolio, symbol, "risk") + qty <- osMaxPos(NULL, timestamp, -2000, "", side, portfolio, symbol, type) expect_equal(qty, -2000) - qty <- osMaxPos(NULL, timestamp, -2000, "", NULL, portfolio, symbol, "risk") + qty <- osMaxPos(NULL, timestamp, -2000, "", NULL, portfolio, symbol, type) 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) + qty <- osMaxPos(NULL, timestamp, -longPos*2, "", side, portfolio, symbol, type) + expect_equal(qty, -longPos*2) + qty <- osMaxPos(NULL, timestamp, -longPos*2, "", NULL, portfolio, symbol, type) + expect_equal(qty, -longPos*2) }) # 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") +# qty <- osMaxPos(NULL, timestamp, 1000, "", side, portfolio, symbol, type) +# qty <- osMaxPos(NULL, timestamp, 1000, "", NULL, portfolio, symbol, type) #}) # #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") +# qty <- osMaxPos(NULL, timestamp, 2000, "", side, portfolio, symbol, type) +# qty <- osMaxPos(NULL, timestamp, 2000, "", NULL, portfolio, symbol, type) #}) ############################################################################### # long position, ruletype != "risk" +type <- "" + 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, "")) + expect_error(osMaxPos(NULL, timestamp, "all", "", side, portfolio, symbol, type)) }) test_that("reduce long", { - qty <- osMaxPos(NULL, timestamp, -2000, "", "long", portfolio, symbol, "") + qty <- osMaxPos(NULL, timestamp, -2000, "", side, portfolio, symbol, type) expect_equal(qty, -2000) - qty <- osMaxPos(NULL, timestamp, -2000, "", NULL, portfolio, symbol, "") + qty <- osMaxPos(NULL, timestamp, -2000, "", NULL, portfolio, symbol, type) 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) + qty <- osMaxPos(NULL, timestamp, -longPos*2, "", side, portfolio, symbol, type) + expect_equal(qty, -longPos) + qty <- osMaxPos(NULL, timestamp, -longPos*2, "", NULL, portfolio, symbol, type) + expect_equal(qty, -longPos) }) -test_that("increase long within limits", { - qty <- osMaxPos(NULL, timestamp, 1000, "", "long", portfolio, symbol, "") +test_that("increase long within limits, < clip size", { + qty <- osMaxPos(NULL, timestamp, 1000, "", side, portfolio, symbol, type) expect_equal(qty, 1000) - qty <- osMaxPos(NULL, timestamp, 1000, "", NULL, portfolio, symbol, "") + qty <- osMaxPos(NULL, timestamp, 1000, "", NULL, portfolio, symbol, type) expect_equal(qty, 1000) }) +test_that("increase long within limits, > clip size", { + qty <- osMaxPos(NULL, timestamp, 1500, "", side, portfolio, symbol, type) + expect_equal(qty, 1000) + qty <- osMaxPos(NULL, timestamp, 1500, "", NULL, portfolio, symbol, type) + expect_equal(qty, 1000) +}) + test_that("increase long beyond limits", { - qty <- osMaxPos(NULL, timestamp, 2000, "", "long", portfolio, symbol, "") + qty <- osMaxPos(NULL, timestamp, 2000, "", side, portfolio, symbol, type) expect_equal(qty, 1000) - qty <- osMaxPos(NULL, timestamp, 2000, "", NULL, portfolio, symbol, "") + qty <- osMaxPos(NULL, timestamp, 2000, "", NULL, portfolio, symbol, type) expect_equal(qty, 1000) }) From noreply at r-forge.r-project.org Sat Mar 26 16:10:30 2016 From: noreply at r-forge.r-project.org (noreply at r-forge.r-project.org) Date: Sat, 26 Mar 2016 16:10:30 +0100 (CET) Subject: [Blotter-commits] r1739 - in pkg/quantstrat: . R man Message-ID: <20160326151030.80D541874F7@r-forge.r-project.org> Author: bodanker Date: 2016-03-26 16:10:30 +0100 (Sat, 26 Mar 2016) New Revision: 1739 Modified: pkg/quantstrat/DESCRIPTION pkg/quantstrat/NAMESPACE pkg/quantstrat/R/quantstrat-package.R pkg/quantstrat/man/chart.forward.Rd pkg/quantstrat/man/initOrders.Rd pkg/quantstrat/man/tradeGraphs.Rd Log: Add base imports, roxygenize docs, bump version Modified: pkg/quantstrat/DESCRIPTION =================================================================== --- pkg/quantstrat/DESCRIPTION 2016-03-26 14:35:13 UTC (rev 1738) +++ pkg/quantstrat/DESCRIPTION 2016-03-26 15:10:30 UTC (rev 1739) @@ -1,7 +1,7 @@ Package: quantstrat Type: Package Title: Quantitative Strategy Model Framework -Version: 0.9.1709 +Version: 0.9.1739 Date: $Date$ Author: Peter Carl, Brian G. Peterson, Joshua Ulrich, Jan Humme Depends: @@ -12,6 +12,7 @@ FinancialInstrument(>= 0.12.5), foreach(>= 1.4.0) Imports: + methods, iterators, zoo Suggests: @@ -30,6 +31,6 @@ Michael Guan, Jeffrey A. Ryan, Garrett See LazyLoad: yes License: GPL-3 -Copyright: (c) 2009-2015 +Copyright: (c) 2009-2016 ByteCompile: TRUE -RoxygenNote: 5.0.0 +RoxygenNote: 5.0.1 Modified: pkg/quantstrat/NAMESPACE =================================================================== --- pkg/quantstrat/NAMESPACE 2016-03-26 14:35:13 UTC (rev 1738) +++ pkg/quantstrat/NAMESPACE 2016-03-26 15:10:30 UTC (rev 1739) @@ -67,5 +67,21 @@ import(quantmod) import(xts) import(zoo) +importFrom(grDevices,dev.new) +importFrom(graphics,abline) +importFrom(graphics,boxplot) +importFrom(graphics,lines) +importFrom(graphics,par) +importFrom(graphics,plot) importFrom(iterators,iter) +importFrom(methods,hasArg) +importFrom(stats,as.formula) +importFrom(stats,coef) +importFrom(stats,end) +importFrom(stats,lm) +importFrom(stats,na.omit) +importFrom(stats,start) +importFrom(stats,time) +importFrom(utils,glob2rx) +importFrom(utils,installed.packages) useDynLib(quantstrat) Modified: pkg/quantstrat/R/quantstrat-package.R =================================================================== --- pkg/quantstrat/R/quantstrat-package.R 2016-03-26 14:35:13 UTC (rev 1738) +++ pkg/quantstrat/R/quantstrat-package.R 2016-03-26 15:10:30 UTC (rev 1739) @@ -102,5 +102,10 @@ #' @keywords package # @examples #' -#' @import blotter FinancialInstrument foreach quantmod xts zoo +#' @import blotter FinancialInstrument foreach methods quantmod xts zoo +#' @importFrom grDevices dev.new heat.colors +#' @importFrom graphics abline boxplot lines par plot +#' @importFrom methods hasArg +#' @importFrom stats as.formula coef end lm na.omit start time +#' @importFrom utils glob2rx installed.packages NULL Modified: pkg/quantstrat/man/chart.forward.Rd =================================================================== --- pkg/quantstrat/man/chart.forward.Rd 2016-03-26 14:35:13 UTC (rev 1738) +++ pkg/quantstrat/man/chart.forward.Rd 2016-03-26 15:10:30 UTC (rev 1739) @@ -7,7 +7,7 @@ chart.forward(audit.filename) } \arguments{ -\item{audit.filename}{name of .audit environment file as produced by walk.forward() +\item{audit.filename}{name of .audit environment file as produced by walk.forward(). Filename will match pattern [audit.prefix].results.RData.} } \description{ Modified: pkg/quantstrat/man/initOrders.Rd =================================================================== --- pkg/quantstrat/man/initOrders.Rd 2016-03-26 14:35:13 UTC (rev 1738) +++ pkg/quantstrat/man/initOrders.Rd 2016-03-26 15:10:30 UTC (rev 1739) @@ -4,7 +4,7 @@ \alias{initOrders} \title{initialize order container} \usage{ -initOrders(portfolio = NULL, symbols = NULL, initDate = "1999-12-31", ...) +initOrders(portfolio = NULL, symbols = NULL, initDate = "1950-01-01", ...) } \arguments{ \item{portfolio}{text name of the portfolio to associate the order book with} Modified: pkg/quantstrat/man/tradeGraphs.Rd =================================================================== --- pkg/quantstrat/man/tradeGraphs.Rd 2016-03-26 14:35:13 UTC (rev 1738) +++ pkg/quantstrat/man/tradeGraphs.Rd 2016-03-26 15:10:30 UTC (rev 1739) @@ -29,7 +29,7 @@ tradeGraphs ( stats = stats, free.params = c("Param.indicator.1.nFast", "Param.indicator.2.nSlow"), -params.filter = "Param.indicator.2.nSlow < 40 & Param.indicator.1.nFast > 5" + params.filter = "Param.indicator.2.nSlow < 40 & Param.indicator.1.nFast > 5" statistics = c("Net.Trading.PL", "maxDrawdown", "Avg.Trade.PL", "Num.Trades") title = 'Luxor' ) From noreply at r-forge.r-project.org Wed Mar 30 21:40:42 2016 From: noreply at r-forge.r-project.org (noreply at r-forge.r-project.org) Date: Wed, 30 Mar 2016 21:40:42 +0200 (CEST) Subject: [Blotter-commits] r1740 - in pkg/blotter: R tests/unitTests Message-ID: <20160330194042.6FD88186EE1@r-forge.r-project.org> Author: bodanker Date: 2016-03-30 21:40:41 +0200 (Wed, 30 Mar 2016) New Revision: 1740 Modified: pkg/blotter/R/addTxn.R pkg/blotter/tests/unitTests/runitAddTxn.R pkg/blotter/tests/unitTests/runitUpdatePortf.R Log: Fix transaction fees in addTxns addTxns did not calculate transaction value (Txn.Value) gross of fees as addTxn does. It also calculated Net.Txn.Realized.PL incorrectly, by subtracting transaction fees instead of adding them. Add unit test to ensure addTxns and addTxn produce the same transaction table using the amzn_test data. Set verbose=TRUE in addTxn calls in other tests, and make sure they clean up correctly (account/portfolio names were incorrect). No need to clean up the IBM object, since it will be available for garbage collection after the function exits. Modified: pkg/blotter/R/addTxn.R =================================================================== --- pkg/blotter/R/addTxn.R 2016-03-26 15:10:30 UTC (rev 1739) +++ pkg/blotter/R/addTxn.R 2016-03-30 19:40:41 UTC (rev 1740) @@ -236,7 +236,7 @@ } rm(Pos, PosCrossZero) # clean up # calculate transaction values - NewTxns$Txn.Value <- .calcTxnValue(NewTxns$Txn.Qty, NewTxns$Txn.Price, NewTxns$Txn.Fees, ConMult) + NewTxns$Txn.Value <- .calcTxnValue(NewTxns$Txn.Qty, NewTxns$Txn.Price, 0, ConMult) # Gross of fees NewTxns$Txn.Avg.Cost <- .calcTxnAvgCost(NewTxns$Txn.Value, NewTxns$Txn.Qty, ConMult) # intermediate objects to aid in vectorization; only first element is non-zero initPosQty <- initPosAvgCost <- numeric(nrow(NewTxns)) @@ -251,7 +251,7 @@ lagPosQty <- c(initPosQty[1], NewTxns$Pos.Qty[-nrow(NewTxns)]) NewTxns$Gross.Txn.Realized.PL <- NewTxns$Txn.Qty * ConMult * (lagPosAvgCost - NewTxns$Txn.Avg.Cost) NewTxns$Gross.Txn.Realized.PL[abs(lagPosQty) < abs(NewTxns$Pos.Qty) | lagPosQty == 0] <- 0 - NewTxns$Net.Txn.Realized.PL <- NewTxns$Gross.Txn.Realized.PL - NewTxns$Txn.Fees + NewTxns$Net.Txn.Realized.PL <- NewTxns$Gross.Txn.Realized.PL + NewTxns$Txn.Fees NewTxns$Con.Mult <- ConMult # update portfolio with new transactions Modified: pkg/blotter/tests/unitTests/runitAddTxn.R =================================================================== --- pkg/blotter/tests/unitTests/runitAddTxn.R 2016-03-26 15:10:30 UTC (rev 1739) +++ pkg/blotter/tests/unitTests/runitAddTxn.R 2016-03-30 19:40:41 UTC (rev 1740) @@ -5,8 +5,7 @@ # remove objects created by unit tests try(rm_currencies("USD")) try(rm_stocks(symbols)) - try(rm(list=p, pos=.blotter)) - try(rm(IBM)) + try(rm(list=paste0("portfolio.",p), pos=.blotter)) }) currency("USD") @@ -22,16 +21,16 @@ # Trades must be made in date order. # Make a couple of trades in IBM - addTxn(p, "IBM", '2007-01-03', 50, 96.5, TxnFees=-0.05 * 50) - addTxn(p, "IBM", '2007-01-04', -50, 97.1, TxnFees=-0.05 * 50) - addTxn(p, "IBM", '2007-01-08', -10, 99.2, TxnFees=-0.05 * 10) - addTxn(p, "IBM", '2007-01-09', -10, 100.1, TxnFees=-0.05 * 10) - addTxn(p, "IBM", '2007-01-17', -10, 100.25, TxnFees=-0.05 * 10) - addTxn(p, "IBM", '2007-01-19', 30, 95, TxnFees=-0.05 * 30) - addTxn(p, "IBM", '2007-01-22', 25, 96.3, TxnFees=-0.05 * 25) - addTxn(p, "IBM", '2007-01-23', 25, 96.42, TxnFees=-0.05 * 25) - addTxn(p, "IBM", '2007-01-26', -25, 97.52, TxnFees=-0.05 * 25) - addTxn(p, "IBM", '2007-01-31', -25, 98.80, TxnFees=-0.05 * 25) + addTxn(p, "IBM", '2007-01-03', 50, 96.5, TxnFees=-0.05 * 50, verbose=FALSE) + addTxn(p, "IBM", '2007-01-04', -50, 97.1, TxnFees=-0.05 * 50, verbose=FALSE) + addTxn(p, "IBM", '2007-01-08', -10, 99.2, TxnFees=-0.05 * 10, verbose=FALSE) + addTxn(p, "IBM", '2007-01-09', -10, 100.1, TxnFees=-0.05 * 10, verbose=FALSE) + addTxn(p, "IBM", '2007-01-17', -10, 100.25, TxnFees=-0.05 * 10, verbose=FALSE) + addTxn(p, "IBM", '2007-01-19', 30, 95, TxnFees=-0.05 * 30, verbose=FALSE) + addTxn(p, "IBM", '2007-01-22', 25, 96.3, TxnFees=-0.05 * 25, verbose=FALSE) + addTxn(p, "IBM", '2007-01-23', 25, 96.42, TxnFees=-0.05 * 25, verbose=FALSE) + addTxn(p, "IBM", '2007-01-26', -25, 97.52, TxnFees=-0.05 * 25, verbose=FALSE) + addTxn(p, "IBM", '2007-01-31', -25, 98.80, TxnFees=-0.05 * 25, verbose=FALSE) portfolio <- getPortfolio(p) transactions <- portfolio$symbols[["IBM"]]$txn @@ -42,3 +41,38 @@ # summary <- calcPortfSummary(portfolio) } +test.addTxns <- function() { + on.exit({ + # remove objects created by unit tests + try(rm_currencies("USD"), silent=TRUE) + try(rm_stocks("AMZN"), silent=TRUE) + try(rm(list=c("account.amzn_acct","portfolio.amzn_txn","portfolio.amzn_txns"), pos=.blotter), silent=TRUE) + }) + + # load the example data + data("amzn", package="blotter") + # add transaction fees + amzn.trades <- merge(amzn.trades, TxnFees=-0.1) + currency("USD") + stock("AMZN", currency="USD", multiplier=1) + + # Initialize the account/portfolios + initAcct("amzn_acct", portfolios=c("amzn_txn","amzn_txns"), initEq=10000) + initPortf("amzn_txn", symbols="AMZN") + initPortf("amzn_txns", symbols="AMZN") + + # Add the transactions to the portfolios + # addTxns: + addTxns("amzn_txns", "AMZN", TxnData=amzn.trades) + # addTxn: + for(i in 1:nrow(amzn.trades)) { + TxnTime <- index(amzn.trades)[i] + amzn.trade <- data.frame(amzn.trades[i,]) + with(amzn.trade, addTxn("amzn_txn","AMZN", TxnTime, TxnQty, TxnPrice, TxnFees=TxnFees, verbose=FALSE)) + } + + t1 <- getPortfolio("amzn_txn")$symbols$AMZN$txn + t2 <- getPortfolio("amzn_txns")$symbols$AMZN$txn + checkIdentical(t1, t2) +} + Modified: pkg/blotter/tests/unitTests/runitUpdatePortf.R =================================================================== --- pkg/blotter/tests/unitTests/runitUpdatePortf.R 2016-03-26 15:10:30 UTC (rev 1739) +++ pkg/blotter/tests/unitTests/runitUpdatePortf.R 2016-03-30 19:40:41 UTC (rev 1740) @@ -5,8 +5,7 @@ # remove objects created by unit tests try(rm_currencies("USD")) try(rm_stocks(symbols)) - try(rm(list=c(p1,a1), pos=.blotter)) - try(rm(IBM)) + try(rm(list=c(paste0("portfolio.",p1),paste0("account.",a1)), pos=.blotter)) }) currency("USD") @@ -18,7 +17,7 @@ ## simple portfolio with one transaction p1 <- initPortf(name="p1runitUpdatePortf", symbols=symbols) - p1 <- addTxn(Portfolio="p1runitUpdatePortf", Symbol="IBM", TxnDate='2007-01-04', TxnQty=100, TxnPrice=96.5, TxnFees=-0.05*100) + p1 <- addTxn(Portfolio="p1runitUpdatePortf", Symbol="IBM", TxnDate='2007-01-04', TxnQty=100, TxnPrice=96.5, TxnFees=-0.05*100, verbose=FALSE) p1 <- updatePortf(Portfolio="p1runitUpdatePortf", Dates='2007-01-03::2007-01-10') a1 <- initAcct(name="a1runitUpdatePortf", portfolios="p1runitUpdatePortf") a1 <- updateAcct(a1,'2007-01') @@ -27,7 +26,7 @@ ## (really) simple transaction cost function fiveCents <- function(qty, prc, ...) return(-0.05*qty) p2 <- initPortf(name="p2runitUpdatePortf", symbols=symbols) - p2 <- addTxn(Portfolio="p2runitUpdatePortf", Symbol="IBM", TxnDate='2007-01-04', TxnQty=100, TxnPrice=96.5, TxnFees=fiveCents) + p2 <- addTxn(Portfolio="p2runitUpdatePortf", Symbol="IBM", TxnDate='2007-01-04', TxnQty=100, TxnPrice=96.5, TxnFees=fiveCents, verbose=FALSE) p2 <- updatePortf(Portfolio="p2runitUpdatePortf", Dates='2007-01-03::2007-01-10') a2 <- initAcct(name="a2runitUpdatePortf", portfolios="p2runitUpdatePortf") a2 <- updateAcct(a2,'2007-01') From noreply at r-forge.r-project.org Wed Mar 30 23:37:25 2016 From: noreply at r-forge.r-project.org (noreply at r-forge.r-project.org) Date: Wed, 30 Mar 2016 23:37:25 +0200 (CEST) Subject: [Blotter-commits] r1741 - in pkg/blotter: . R Message-ID: <20160330213725.97EBE187EB0@r-forge.r-project.org> Author: bodanker Date: 2016-03-30 23:37:25 +0200 (Wed, 30 Mar 2016) New Revision: 1741 Modified: pkg/blotter/DESCRIPTION pkg/blotter/R/tradeStats.R Log: Determine 'trades' without fees, with scratches Transaction fees are realized on every transaction, so do not use non-zero net realized P&L to determine 'trades' for tradeStats. Use non-zero gross realized P&L instead. Also include scratch trades for tradeStats' purposes. The amzn_demo has 5 scratch trades (of 7 total), and that showed the number of transactions (among other things) were not being calculated correctly. Modified: pkg/blotter/DESCRIPTION =================================================================== --- pkg/blotter/DESCRIPTION 2016-03-30 19:40:41 UTC (rev 1740) +++ pkg/blotter/DESCRIPTION 2016-03-30 21:37:25 UTC (rev 1741) @@ -2,7 +2,7 @@ Type: Package Title: Tools for Transaction-Oriented Trading Systems Development -Version: 0.9.1695 +Version: 0.9.1741 Date: $Date$ Author: Peter Carl [aut], Brian G. Peterson [aut, cre], @@ -39,5 +39,5 @@ Hmisc, RUnit, URL: https://r-forge.r-project.org/projects/blotter/ -Copyright: (c) 2008-2015 +Copyright: (c) 2008-2016 ByteCompile: TRUE Modified: pkg/blotter/R/tradeStats.R =================================================================== --- pkg/blotter/R/tradeStats.R 2016-03-30 19:40:41 UTC (rev 1740) +++ pkg/blotter/R/tradeStats.R 2016-03-30 21:37:25 UTC (rev 1741) @@ -114,9 +114,13 @@ posPL <- Portfolio$symbols[[symbol]]$posPL posPL <- posPL[-1,] - PL.gt0 <- txn$Net.Txn.Realized.PL[txn$Net.Txn.Realized.PL > 0] - PL.lt0 <- txn$Net.Txn.Realized.PL[txn$Net.Txn.Realized.PL < 0] - PL.ne0 <- txn$Net.Txn.Realized.PL[txn$Net.Txn.Realized.PL != 0] + # Use gross transaction P&L to identify transactions that realized + # (non-fee) P&L, but use net transaction P&L to calculate statistics. + PL.gt0 <- txn$Net.Txn.Realized.PL[txn$Gross.Txn.Realized.PL > 0] + PL.lt0 <- txn$Net.Txn.Realized.PL[txn$Gross.Txn.Realized.PL < 0] + PL.scratch <- txn$Pos.Qty == 0 & lag(txn$Pos.Qty) != 0 + PL.scratch[1] <- FALSE # Set first NA to FALSE + PL.ne0 <- txn$Net.Txn.Realized.PL[txn$Gross.Txn.Realized.PL != 0 | PL.scratch] if(length(PL.ne0) == 0) {