From noreply at r-forge.r-project.org Sun Apr 3 00:37:36 2016 From: noreply at r-forge.r-project.org (noreply at r-forge.r-project.org) Date: Sun, 3 Apr 2016 00:37:36 +0200 (CEST) Subject: [Blotter-commits] r1742 - in pkg/blotter/R: . .Rproj.user .Rproj.user/2C25DC80 .Rproj.user/2C25DC80/pcs .Rproj.user/2C25DC80/sdb .Rproj.user/2C25DC80/sdb/per .Rproj.user/2C25DC80/sdb/prop .Rproj.user/2C25DC80/sdb/s-3A141202 Message-ID: <20160402223736.94964187ED6@r-forge.r-project.org> Author: jaymon0703 Date: 2016-04-03 00:37:35 +0200 (Sun, 03 Apr 2016) New Revision: 1742 Added: pkg/blotter/R/.Rhistory pkg/blotter/R/.Rproj.user/ pkg/blotter/R/.Rproj.user/2C25DC80/ pkg/blotter/R/.Rproj.user/2C25DC80/build_options pkg/blotter/R/.Rproj.user/2C25DC80/cpp-definition-cache pkg/blotter/R/.Rproj.user/2C25DC80/ctx/ pkg/blotter/R/.Rproj.user/2C25DC80/pcs/ pkg/blotter/R/.Rproj.user/2C25DC80/pcs/debug-breakpoints.pper pkg/blotter/R/.Rproj.user/2C25DC80/pcs/files-pane.pper pkg/blotter/R/.Rproj.user/2C25DC80/pcs/source-pane.pper pkg/blotter/R/.Rproj.user/2C25DC80/pcs/windowlayoutstate.pper pkg/blotter/R/.Rproj.user/2C25DC80/pcs/workbench-pane.pper pkg/blotter/R/.Rproj.user/2C25DC80/persistent-state pkg/blotter/R/.Rproj.user/2C25DC80/presentation/ pkg/blotter/R/.Rproj.user/2C25DC80/saved_source_markers pkg/blotter/R/.Rproj.user/2C25DC80/sdb/ pkg/blotter/R/.Rproj.user/2C25DC80/sdb/per/ pkg/blotter/R/.Rproj.user/2C25DC80/sdb/per/t/ pkg/blotter/R/.Rproj.user/2C25DC80/sdb/per/u/ pkg/blotter/R/.Rproj.user/2C25DC80/sdb/prop/ pkg/blotter/R/.Rproj.user/2C25DC80/sdb/prop/209001 pkg/blotter/R/.Rproj.user/2C25DC80/sdb/prop/27FA44DF pkg/blotter/R/.Rproj.user/2C25DC80/sdb/prop/318E0CA1 pkg/blotter/R/.Rproj.user/2C25DC80/sdb/prop/4E8BB848 pkg/blotter/R/.Rproj.user/2C25DC80/sdb/prop/561640DF pkg/blotter/R/.Rproj.user/2C25DC80/sdb/prop/842BCF43 pkg/blotter/R/.Rproj.user/2C25DC80/sdb/prop/965080CC pkg/blotter/R/.Rproj.user/2C25DC80/sdb/prop/96D0BF0B pkg/blotter/R/.Rproj.user/2C25DC80/sdb/prop/B69FB098 pkg/blotter/R/.Rproj.user/2C25DC80/sdb/prop/CCC9F2BC pkg/blotter/R/.Rproj.user/2C25DC80/sdb/prop/F41C06CF pkg/blotter/R/.Rproj.user/2C25DC80/sdb/prop/INDEX pkg/blotter/R/.Rproj.user/2C25DC80/sdb/s-3A141202/ pkg/blotter/R/.Rproj.user/2C25DC80/sdb/s-3A141202/32FAAB64 pkg/blotter/R/.Rproj.user/2C25DC80/sdb/s-3A141202/34B3D60D pkg/blotter/R/.Rproj.user/2C25DC80/sdb/s-3A141202/47E8EEFD pkg/blotter/R/.Rproj.user/2C25DC80/sdb/s-3A141202/A2AD7327 pkg/blotter/R/.Rproj.user/2C25DC80/sdb/s-3A141202/DDB53310 pkg/blotter/R/.Rproj.user/2C25DC80/sdb/s-3A141202/DEC3EC88 pkg/blotter/R/.Rproj.user/2C25DC80/sdb/s-3A141202/E52466C3 pkg/blotter/R/.Rproj.user/2C25DC80/sdb/s-3A141202/F337EE61 pkg/blotter/R/.Rproj.user/2C25DC80/viewer-cache/ pkg/blotter/R/.Rproj.user/2C25DC80/viewer_history/ pkg/blotter/R/R.Rproj pkg/blotter/R/mcsim.R Log: mcsim.R function to graph bands (5%:95%, 25%:50%) from Monte Carlo simulations of back-test results (using summary$EndEq) Added: pkg/blotter/R/.Rhistory =================================================================== --- pkg/blotter/R/.Rhistory (rev 0) +++ pkg/blotter/R/.Rhistory 2016-04-02 22:37:35 UTC (rev 1742) @@ -0,0 +1,512 @@ +is.na(ret[-1,]) +any(is.na(ret[-1,])) +plot(ret) +plot(cumsum(ret)) +ret <- ROC(EndEq) +h <- ggplot(charts, aes(x = index(charts))) + +geom_ribbon(aes(ymin = ret_25, ymax = ret_75, colour = "50%"), alpha = 0.3, fill = "red3") + +geom_ribbon(aes(ymin = ret_5, ymax = ret_95, colour = "90%"), alpha = 0.3, fill = "cornflowerblue") + +theme(axis.text.x = element_text(angle=0, hjust = 0), +axis.title = element_text(face = 'bold', size = 14), +title = element_text(face = 'bold', size = 16), +legend.position = 'bottom', +legend.title = element_blank(), +legend.text = element_text(size = 12), +legend.key.width = unit(2, 'cm')) +h <- h + geom_line(aes(y = cumsum(ret[-1,])), colour = "black", linetype = 1) + +ylab(label="Cumulative Returns") + +xlab(label="Time") + +ggtitle("Returns Distribution") +print(h) +EndEq +ROC(EndEq) +plot(ROC(EndEq)) +class(ret) +#Version 4 +#playing with graphs and shading and legend +t1 <- Sys.time() +# Attach packages. You can install packages via: +# install.packages(c("quantmod","TTR","PerformanceAnalytics")) +library(quantmod) +library(TTR) +library(PerformanceAnalytics) +library(ggplot2) +library(timeSeries) +#Read price data and build xts object +data <- read.csv("C:/Users/jasen/Work/R/simSample.csv", header = TRUE, stringsAsFactors=F) +s1.dates <- as.Date(data[,2], format="%d-%m-%Y") +s1 <- xts(data[,3], s1.dates) +#Calculate ROC +ret <- ROC(s1[,1]) +#Chart cum returns +chart.CumReturns(ret) +#Set up for Sample() and Replicate() +n <- 10000 #number of replications +b <- TRUE #Sample with/without Replacement (Boolean) +ret_sample <- replicate(n,sample(as.vector(ret[-1,]), replace=b)) #use ret[-1] so we exclude 1st NA value from ROC calc +ret_cum_sample <- apply(ret_sample, 2, function(x) cumsum(x)) +ret_cum_samplexts <- xts(ret_cum_sample, s1.dates[-1]) #use s1.dates[-1] so that length of dates is identical to length of ret_sample +#Build the 5% and 95% quantile datasets +ret_5 <- apply(ret_cum_samplexts, 1, function(x) quantile(x, .05)) +ret_5 <- as.xts(ret_5) +ret_95 <- apply(ret_cum_samplexts, 1, function(x) quantile(x, .95)) +ret_95 <- as.xts(ret_95) +ret_25 <- apply(ret_cum_samplexts, 1, function(x) quantile(x, .25)) +ret_25 <- as.xts(ret_25) +ret_75 <- apply(ret_cum_samplexts, 1, function(x) quantile(x, .75)) +ret_75 <- as.xts(ret_75) +charts <- merge(ret_5, ret_95, ret_25, ret_75) +#lets try some shading +h <- ggplot(charts, aes(x = index(charts))) + +geom_ribbon(aes(ymin = ret_25, ymax = ret_75, colour = "50%"), alpha = 0.3, fill = "red3") + +geom_ribbon(aes(ymin = ret_5, ymax = ret_95, colour = "90%"), alpha = 0.3, fill = "cornflowerblue") + +theme(axis.text.x = element_text(angle=0, hjust = 0), +axis.title = element_text(face = 'bold', size = 14), +title = element_text(face = 'bold', size = 16), +legend.position = 'bottom', +legend.title = element_blank(), +legend.text = element_text(size = 12), +legend.key.width = unit(2, 'cm')) +h <- h + geom_line(aes(y = cumsum(ret[-1,])), colour = "black", linetype = 1) + +ylab(label="Cumulative Returns") + +xlab(label="Time") + +ggtitle("Returns Distribution") +h +t2 <- Sys.time() +difftime(t2,t1) +class(ret) +a <- getAccount(Account) +EndEq <- a$summary$End.Eq +a$summary +# Draw the graph with a ribbon +h <- ggplot(charts, aes(x = index(charts))) + +geom_ribbon(aes(ymin = ret_25, ymax = ret_75, colour = "50%"), alpha = 0.3, fill = "red3") + +geom_ribbon(aes(ymin = ret_5, ymax = ret_95, colour = "90%"), alpha = 0.3, fill = "cornflowerblue") + +theme(axis.text.x = element_text(angle=0, hjust = 0), +axis.title = element_text(face = 'bold', size = 14), +title = element_text(face = 'bold', size = 16), +legend.position = 'bottom', +legend.title = element_blank(), +legend.text = element_text(size = 12), +legend.key.width = unit(2, 'cm')) +#h <- h + geom_line(aes(y = cumsum(ret[-1,])), colour = "black", linetype = 1) + +h <- h + geom_line(aes(y = EndEq[-1,])), colour = "black", linetype = 1) + +ylab(label="Cumulative Returns") + +xlab(label="Time") + +ggtitle("Returns Distribution") +h +EndEq +class(EndEq) +# Draw the graph with a ribbon +h <- ggplot(charts, aes(x = index(charts))) + +geom_ribbon(aes(ymin = ret_25, ymax = ret_75, colour = "50%"), alpha = 0.3, fill = "red3") + +geom_ribbon(aes(ymin = ret_5, ymax = ret_95, colour = "90%"), alpha = 0.3, fill = "cornflowerblue") + +theme(axis.text.x = element_text(angle=0, hjust = 0), +axis.title = element_text(face = 'bold', size = 14), +title = element_text(face = 'bold', size = 16), +legend.position = 'bottom', +legend.title = element_blank(), +legend.text = element_text(size = 12), +legend.key.width = unit(2, 'cm')) +#h <- h + geom_line(aes(y = cumsum(ret[-1,])), colour = "black", linetype = 1) + +h <- h + #geom_line(aes(y = EndEq[-1,])), colour = "black", linetype = 1) + +ylab(label="Cumulative Returns") + +xlab(label="Time") + +ggtitle("Returns Distribution") +h +#' Retrieves the most recent value of the capital account +#' @param Account string identifier of account +#' @param n number of monte carlo simulations +#' @return Graph ggplot of simulations +# Build the function ---------------------------------------------- +mcsimr <- function(Account, n, Replace = TRUE){ +aname<-Account +Account<-try(get(paste("account",aname,sep='.'), envir=.blotter), silent=TRUE) +if(inherits(Account,"try-error")) +stop("Account ", aname, " not found, use initAcct() to create a new account") +a <- getAccount(Account) +EndEq <- a$summary$End.Eq +# # Read price data and build xts object +# data <- read.csv("simSample.csv", header = TRUE, stringsAsFactors=F) +# s1.dates <- as.Date(data[,2], format="%d-%m-%Y") +s1.dates <- index(a$summary) +# s1 <- xts(data[,3], s1.dates) +# Calculate ROC +ret <- ROC(EndEq) +# Chart cum returns +chart.CumReturns(ret) +# Set up for Sample() and Replicate() +ret_sample <- replicate(n,sample(as.vector(ret[-1,]), replace=Replace)) #use ret[-1] so we exclude 1st NA value from ROC calc +ret_cum_sample <- apply(ret_sample, 2, function(x) cumsum(x)) +ret_cum_samplexts <- xts(ret_cum_sample, s1.dates[-1]) #use s1.dates[-1] so that length of dates is identical to length of ret_sample +# Build the 5% and 95% quantile datasets +ret_5 <- apply(ret_cum_samplexts, 1, function(x) quantile(x, .05)) +ret_5 <- as.xts(ret_5) +ret_95 <- apply(ret_cum_samplexts, 1, function(x) quantile(x, .95)) +ret_95 <- as.xts(ret_95) +ret_25 <- apply(ret_cum_samplexts, 1, function(x) quantile(x, .25)) +ret_25 <- as.xts(ret_25) +ret_75 <- apply(ret_cum_samplexts, 1, function(x) quantile(x, .75)) +ret_75 <- as.xts(ret_75) +charts <- merge(ret_5, ret_95, ret_25, ret_75) +# Draw the graph with a ribbon +h <- ggplot(charts, aes(x = index(charts))) + +geom_ribbon(aes(ymin = ret_25, ymax = ret_75, colour = "50%"), alpha = 0.3, fill = "red3") + +geom_ribbon(aes(ymin = ret_5, ymax = ret_95, colour = "90%"), alpha = 0.3, fill = "cornflowerblue") + +theme(axis.text.x = element_text(angle=0, hjust = 0), +axis.title = element_text(face = 'bold', size = 14), +title = element_text(face = 'bold', size = 16), +legend.position = 'bottom', +legend.title = element_blank(), +legend.text = element_text(size = 12), +legend.key.width = unit(2, 'cm')) +#h <- h + geom_line(aes(y = cumsum(ret[-1,])), colour = "black", linetype = 1) + +h <- h + #geom_line(aes(y = EndEq[-1,])), colour = "black", linetype = 1) + +ylab(label="Cumulative Returns") + +xlab(label="Time") + +ggtitle("Returns Distribution") +h +return(h) +} +# Build the function ---------------------------------------------- +mcsim <- function(Account, n, Replace = TRUE){ +aname<-Account +Account<-try(get(paste("account",aname,sep='.'), envir=.blotter), silent=TRUE) +if(inherits(Account,"try-error")) +stop("Account ", aname, " not found, use initAcct() to create a new account") +a <- getAccount(Account) +EndEq <- a$summary$End.Eq +# # Read price data and build xts object +# data <- read.csv("simSample.csv", header = TRUE, stringsAsFactors=F) +# s1.dates <- as.Date(data[,2], format="%d-%m-%Y") +s1.dates <- index(a$summary) +# s1 <- xts(data[,3], s1.dates) +# Calculate ROC +ret <- ROC(EndEq) +# Chart cum returns +chart.CumReturns(ret) +# Set up for Sample() and Replicate() +ret_sample <- replicate(n,sample(as.vector(ret[-1,]), replace=Replace)) #use ret[-1] so we exclude 1st NA value from ROC calc +ret_cum_sample <- apply(ret_sample, 2, function(x) cumsum(x)) +ret_cum_samplexts <- xts(ret_cum_sample, s1.dates[-1]) #use s1.dates[-1] so that length of dates is identical to length of ret_sample +# Build the 5% and 95% quantile datasets +ret_5 <- apply(ret_cum_samplexts, 1, function(x) quantile(x, .05)) +ret_5 <- as.xts(ret_5) +ret_95 <- apply(ret_cum_samplexts, 1, function(x) quantile(x, .95)) +ret_95 <- as.xts(ret_95) +ret_25 <- apply(ret_cum_samplexts, 1, function(x) quantile(x, .25)) +ret_25 <- as.xts(ret_25) +ret_75 <- apply(ret_cum_samplexts, 1, function(x) quantile(x, .75)) +ret_75 <- as.xts(ret_75) +charts <- merge(ret_5, ret_95, ret_25, ret_75) +# Draw the graph with a ribbon +h <- ggplot(charts, aes(x = index(charts))) + +geom_ribbon(aes(ymin = ret_25, ymax = ret_75, colour = "50%"), alpha = 0.3, fill = "red3") + +geom_ribbon(aes(ymin = ret_5, ymax = ret_95, colour = "90%"), alpha = 0.3, fill = "cornflowerblue") + +theme(axis.text.x = element_text(angle=0, hjust = 0), +axis.title = element_text(face = 'bold', size = 14), +title = element_text(face = 'bold', size = 16), +legend.position = 'bottom', +legend.title = element_blank(), +legend.text = element_text(size = 12), +legend.key.width = unit(2, 'cm')) +#h <- h + geom_line(aes(y = cumsum(ret[-1,])), colour = "black", linetype = 1) + +h <- h + #geom_line(aes(y = EndEq[-1,])), colour = "black", linetype = 1) + +ylab(label="Cumulative Returns") + +xlab(label="Time") + +ggtitle("Returns Distribution") +h +return(h) +} +mcsimr("longtrend", 10000,) +mcsim("longtrend", 10000,TRUE) +# This is a very simple trend following strategy for testing the results of: +# Faber, Mebane T., "A Quantitative Approach to Tactical Asset Allocation." +# Journal of Risk Management (Spring 2007). +# The article proposes a very simple quantitative market-timing model. They +# test the model in sample on the US stock market since 1900 before testing +# it out-of-sample in twenty other markets. +# The article discusses a 200-day simple moving average, which is proposed +# in Jeremy Seigel's book "Stocks for the Long Run" for timing the DJIA. He +# concludes that a simple market timing strategy improves the absolute and +# risk adjusted returns over a buy-and-hold strategy. After all transaction +# costs are included, the timing strategy falls short on the absolute return, +# but still provides a better risk-adjusted return. Siegel also tests timing on +# the Nasdaq composite since 1972 and finds better absolute and risk adjusted +# returns. +# The article implements a simpler version of the 200-day SMA, opting for a +# 10-month SMA. Monthly data is more easily available for long periods of time, +# and the lower granularity should translate to lower transaction costs. +# The rules of the system are relatively simple: +# - Buy when monthly price > 10-month SMA +# - Sell and move to cash when monthly price < 10-month SMA +# 1. All entry and exit prices are on the day of the signal at the close. +# 2. All data series are total return series including dividends, updated monthly. +# For the purposes of this demo, we only use price returns. +# 3. Cash returns are estimated with 90-day commercial paper. Margin rates for +# leveraged models are estimated with the broker call rate. Again, for the +# purposes of this demo, we ignore interest and leverage. +# 4. Taxes, commissions, and slippage are excluded. +# This simple strategy is different from well-known trend-following systems in +# three respects. First, there's no shorting. Positions are converted to cash on +# a 'sell' signal, rather than taking a short position. Second, the entire position +# is put on at trade inception. No assumptions are made about increasing position +# size as the trend progresses. Third, there are no stops. If the trend reverts +# quickly, this system will wait for a sell signal before selling the position. +# Data +# Instead of using total returns data, this demo uses monthly data for the SP500 +# downloaded from Yahoo Finance. We'll use about 10 years of data, starting at +# the beginning of 1998. +# Load required libraries +require(quantmod) +require(TTR) +require(blotter) +Sys.setenv(TZ="UTC") +# Try to clean up in case the demo was run previously +try(rm("account.longtrend","portfolio.longtrend",pos=.blotter),silent=TRUE) +try(rm("ltaccount","ltportfolio","ClosePrice","CurrentDate","equity","GSPC","i","initDate","initEq","Posn","UnitSize","verbose"),silent=TRUE) +# Set initial values +initDate='1997-12-31' +initEq=100000 +# Load data with quantmod +print("Loading data") +currency("USD") +stock("GSPC",currency="USD",multiplier=1) +getSymbols('^GSPC', src='yahoo', index.class=c("POSIXt","POSIXct"),from='1998-01-01') +GSPC=to.monthly(GSPC, indexAt='endof', drop.time=FALSE) +# Set up indicators with TTR +print("Setting up indicators") +GSPC$SMA10m <- SMA(GSPC[,grep('Adj',colnames(GSPC))], 10) +# Set up a portfolio object and an account object in blotter +print("Initializing portfolio and account structure") +ltportfolio='longtrend' +ltaccount='longtrend' +initPortf(ltportfolio,'GSPC', initDate=initDate) +initAcct(ltaccount,portfolios='longtrend', initDate=initDate, initEq=initEq) +verbose=TRUE +# Create trades +for( i in 10:NROW(GSPC) ) { +# browser() +CurrentDate=time(GSPC)[i] +cat(".") +equity = getEndEq(ltaccount, CurrentDate) +ClosePrice = as.numeric(Ad(GSPC[i,])) +Posn = getPosQty(ltportfolio, Symbol='GSPC', Date=CurrentDate) +UnitSize = as.numeric(trunc(equity/ClosePrice)) +# Position Entry (assume fill at close) +if( Posn == 0 ) { +# No position, so test to initiate Long position +if( as.numeric(Ad(GSPC[i,])) > as.numeric(GSPC[i,'SMA10m']) ) { +cat('\n') +# Store trade with blotter +addTxn(ltportfolio, Symbol='GSPC', TxnDate=CurrentDate, TxnPrice=ClosePrice, TxnQty = UnitSize , TxnFees=0, verbose=verbose) +} +} else { +# Have a position, so check exit +if( as.numeric(Ad(GSPC[i,])) < as.numeric(GSPC[i,'SMA10m'])) { +cat('\n') +# Store trade with blotter +addTxn(ltportfolio, Symbol='GSPC', TxnDate=CurrentDate, TxnPrice=ClosePrice, TxnQty = -Posn , TxnFees=0, verbose=verbose) +} +} +# Calculate P&L and resulting equity with blotter +updatePortf(ltportfolio, Dates = CurrentDate) +updateAcct(ltaccount, Dates = CurrentDate) +updateEndEq(ltaccount, Dates = CurrentDate) +} # End dates loop +cat('\n') +# Chart results with quantmod +chart.Posn(ltportfolio, Symbol = 'GSPC', Dates = '1998::') +plot(add_SMA(n=10,col='darkgreen', on=1)) +#look at a transaction summary +getTxns(Portfolio="longtrend", Symbol="GSPC") +# Copy the results into the local environment +print("Retrieving resulting portfolio and account") +ltportfolio = getPortfolio("longtrend") +ltaccount = getAccount("longtrend") +############################################################################### +# Blotter: Tools for transaction-oriented trading systems development +# for R (see http://r-project.org/) +# Copyright (c) 2008 Peter Carl and Brian G. Peterson +# +# This library is distributed under the terms of the GNU Public License (GPL) +# for full details see the file COPYING +# +# $Id: longtrend.R 1483 2013-07-22 01:27:14Z bodanker $ +# +############################################################################### +# Build the function ---------------------------------------------- +mcsim <- function(Account, n, Replace = TRUE){ +aname<-Account +Account<-try(get(paste("account",aname,sep='.'), envir=.blotter), silent=TRUE) +if(inherits(Account,"try-error")) +stop("Account ", aname, " not found, use initAcct() to create a new account") +a <- getAccount(Account) +EndEq <- a$summary$End.Eq +# # Read price data and build xts object +# data <- read.csv("simSample.csv", header = TRUE, stringsAsFactors=F) +# s1.dates <- as.Date(data[,2], format="%d-%m-%Y") +s1.dates <- index(a$summary) +# s1 <- xts(data[,3], s1.dates) +# Calculate ROC +ret <- ROC(EndEq) +# Chart cum returns +chart.CumReturns(ret) +# Set up for Sample() and Replicate() +ret_sample <- replicate(n,sample(as.vector(ret[-1,]), replace=Replace)) #use ret[-1] so we exclude 1st NA value from ROC calc +ret_cum_sample <- apply(ret_sample, 2, function(x) cumsum(x)) +ret_cum_samplexts <- xts(ret_cum_sample, s1.dates[-1]) #use s1.dates[-1] so that length of dates is identical to length of ret_sample +# Build the 5% and 95% quantile datasets +ret_5 <- apply(ret_cum_samplexts, 1, function(x) quantile(x, .05)) +ret_5 <- as.xts(ret_5) +ret_95 <- apply(ret_cum_samplexts, 1, function(x) quantile(x, .95)) +ret_95 <- as.xts(ret_95) +ret_25 <- apply(ret_cum_samplexts, 1, function(x) quantile(x, .25)) +ret_25 <- as.xts(ret_25) +ret_75 <- apply(ret_cum_samplexts, 1, function(x) quantile(x, .75)) +ret_75 <- as.xts(ret_75) +charts <- merge(ret_5, ret_95, ret_25, ret_75) +# Draw the graph with a ribbon +h <- ggplot(charts, aes(x = index(charts))) + +geom_ribbon(aes(ymin = ret_25, ymax = ret_75, colour = "50%"), alpha = 0.3, fill = "red3") + +geom_ribbon(aes(ymin = ret_5, ymax = ret_95, colour = "90%"), alpha = 0.3, fill = "cornflowerblue") + +theme(axis.text.x = element_text(angle=0, hjust = 0), +axis.title = element_text(face = 'bold', size = 14), +title = element_text(face = 'bold', size = 16), +legend.position = 'bottom', +legend.title = element_blank(), +legend.text = element_text(size = 12), +legend.key.width = unit(2, 'cm')) +#h <- h + geom_line(aes(y = cumsum(ret[-1,])), colour = "black", linetype = 1) + +h <- h + #geom_line(aes(y = EndEq[-1,])), colour = "black", linetype = 1) + +ylab(label="Cumulative Returns") + +xlab(label="Time") + +ggtitle("Returns Distribution") +h +return(h) +} +mcsim("longtrend", 10000,TRUE) +Account <- "longtrend" +a <- getAccount(Account) +EndEq <- a$summary$End.Eq +View(EndEq) +s1.dates <- index(a$summary) +ret <- ROC(EndEq) +# Chart cum returns +chart.CumReturns(ret) +# Set up for Sample() and Replicate() +ret_sample <- replicate(n,sample(as.vector(ret[-1,]), replace=Replace)) #use ret[-1] so we exclude 1st NA value from ROC calc +ret_cum_sample <- apply(ret_sample, 2, function(x) cumsum(x)) +ret_cum_samplexts <- xts(ret_cum_sample, s1.dates[-1]) #use s1.dates[-1] so that length of dates is identical to length of ret_sample +# Build the 5% and 95% quantile datasets +ret_5 <- apply(ret_cum_samplexts, 1, function(x) quantile(x, .05)) +n <- 100 +ret_sample <- replicate(n,sample(as.vector(ret[-1,]), replace=Replace)) #use ret[-1] so we exclude 1st NA value from ROC calc +Replace = TRUE +ret_sample <- replicate(n,sample(as.vector(ret[-1,]), replace=Replace)) #use ret[-1] so we exclude 1st NA value from ROC calc +ret_cum_sample <- apply(ret_sample, 2, function(x) cumsum(x)) +ret_cum_samplexts <- xts(ret_cum_sample, s1.dates[-1]) #use s1.dates[-1] so that length of dates is identical to length of ret_sample +# Build the 5% and 95% quantile datasets +ret_5 <- apply(ret_cum_samplexts, 1, function(x) quantile(x, .05)) +ret_5 <- as.xts(ret_5) +ret_95 <- apply(ret_cum_samplexts, 1, function(x) quantile(x, .95)) +ret_95 <- as.xts(ret_95) +ret_25 <- apply(ret_cum_samplexts, 1, function(x) quantile(x, .25)) +ret_25 <- as.xts(ret_25) +ret_75 <- apply(ret_cum_samplexts, 1, function(x) quantile(x, .75)) +ret_75 <- as.xts(ret_75) +charts <- merge(ret_5, ret_95, ret_25, ret_75) +# Draw the graph with a ribbon +h <- ggplot(charts, aes(x = index(charts))) + +geom_ribbon(aes(ymin = ret_25, ymax = ret_75, colour = "50%"), alpha = 0.3, fill = "red3") + +geom_ribbon(aes(ymin = ret_5, ymax = ret_95, colour = "90%"), alpha = 0.3, fill = "cornflowerblue") + +theme(axis.text.x = element_text(angle=0, hjust = 0), +axis.title = element_text(face = 'bold', size = 14), +title = element_text(face = 'bold', size = 16), +legend.position = 'bottom', +legend.title = element_blank(), +legend.text = element_text(size = 12), +legend.key.width = unit(2, 'cm')) +#h <- h + geom_line(aes(y = cumsum(ret[-1,])), colour = "black", linetype = 1) + +h <- h + #geom_line(aes(y = EndEq[-1,])), colour = "black", linetype = 1) + +ylab(label="Cumulative Returns") + +xlab(label="Time") + +ggtitle("Returns Distribution") +h +return(h) +mcsim("longtrend", 100, TRUE) +aname<-Account +Account<-try(get(paste("account",aname,sep='.'), envir=.blotter), silent=TRUE) +if(inherits(Account,"try-error")) +stop("Account ", aname, " not found, use initAcct() to create a new account") +mcsim <- function(Account, n = 100, Replace = TRUE){ +# aname<-Account +# Account<-try(get(paste("account",aname,sep='.'), envir=.blotter), silent=TRUE) +# if(inherits(Account,"try-error")) +# stop("Account ", aname, " not found, use initAcct() to create a new account") +# +a <- getAccount(Account) +EndEq <- a$summary$End.Eq +# # Read price data and build xts object +# data <- read.csv("simSample.csv", header = TRUE, stringsAsFactors=F) +# s1.dates <- as.Date(data[,2], format="%d-%m-%Y") +s1.dates <- index(a$summary) +# s1 <- xts(data[,3], s1.dates) +# Calculate ROC +ret <- ROC(EndEq) +# Chart cum returns +chart.CumReturns(ret) +# Set up for Sample() and Replicate() +ret_sample <- replicate(n,sample(as.vector(ret[-1,]), replace=Replace)) #use ret[-1] so we exclude 1st NA value from ROC calc +ret_cum_sample <- apply(ret_sample, 2, function(x) cumsum(x)) +ret_cum_samplexts <- xts(ret_cum_sample, s1.dates[-1]) #use s1.dates[-1] so that length of dates is identical to length of ret_sample +# Build the 5% and 95% quantile datasets +ret_5 <- apply(ret_cum_samplexts, 1, function(x) quantile(x, .05)) +ret_5 <- as.xts(ret_5) +ret_95 <- apply(ret_cum_samplexts, 1, function(x) quantile(x, .95)) +ret_95 <- as.xts(ret_95) +ret_25 <- apply(ret_cum_samplexts, 1, function(x) quantile(x, .25)) +ret_25 <- as.xts(ret_25) +ret_75 <- apply(ret_cum_samplexts, 1, function(x) quantile(x, .75)) +ret_75 <- as.xts(ret_75) +charts <- merge(ret_5, ret_95, ret_25, ret_75) +# Draw the graph with a ribbon +h <- ggplot(charts, aes(x = index(charts))) + +geom_ribbon(aes(ymin = ret_25, ymax = ret_75, colour = "50%"), alpha = 0.3, fill = "red3") + +geom_ribbon(aes(ymin = ret_5, ymax = ret_95, colour = "90%"), alpha = 0.3, fill = "cornflowerblue") + +theme(axis.text.x = element_text(angle=0, hjust = 0), +axis.title = element_text(face = 'bold', size = 14), +title = element_text(face = 'bold', size = 16), +legend.position = 'bottom', +legend.title = element_blank(), +legend.text = element_text(size = 12), +legend.key.width = unit(2, 'cm')) +#h <- h + geom_line(aes(y = cumsum(ret[-1,])), colour = "black", linetype = 1) + +h <- h + #geom_line(aes(y = EndEq[-1,])), colour = "black", linetype = 1) + +ylab(label="Cumulative Returns") + +xlab(label="Time") + +ggtitle("Returns Distribution") +#h +return(h) +} +mcsim("longtrend", 100, TRUE) +load_all() +require(devtools) +load_all() +require(roxygen2) +load_all() +require(devtools) +load_all() +getwd() +require(roxygen2) +devtools::load_all(".") +devtools::load_all(".") +load_all() +install.packages("Rtools") +R CMD check blotter +R CMD check +R CMD check "blotter" +dev_tools::load_all +require(devtools) +devtools::load_all +devtools::load_all() Added: pkg/blotter/R/.Rproj.user/2C25DC80/build_options =================================================================== --- pkg/blotter/R/.Rproj.user/2C25DC80/build_options (rev 0) +++ pkg/blotter/R/.Rproj.user/2C25DC80/build_options 2016-04-02 22:37:35 UTC (rev 1742) @@ -0,0 +1,4 @@ +auto_roxygenize_for_build_and_reload="1" +auto_roxygenize_for_build_package="1" +auto_roxygenize_for_check="1" +makefile_args="" Added: pkg/blotter/R/.Rproj.user/2C25DC80/cpp-definition-cache =================================================================== --- pkg/blotter/R/.Rproj.user/2C25DC80/cpp-definition-cache (rev 0) +++ pkg/blotter/R/.Rproj.user/2C25DC80/cpp-definition-cache 2016-04-02 22:37:35 UTC (rev 1742) @@ -0,0 +1,2 @@ +[ +] \ No newline at end of file Added: pkg/blotter/R/.Rproj.user/2C25DC80/pcs/debug-breakpoints.pper =================================================================== --- pkg/blotter/R/.Rproj.user/2C25DC80/pcs/debug-breakpoints.pper (rev 0) +++ pkg/blotter/R/.Rproj.user/2C25DC80/pcs/debug-breakpoints.pper 2016-04-02 22:37:35 UTC (rev 1742) @@ -0,0 +1,6 @@ +{ + "debugBreakpointsState" : { + "breakpoints" : [ + ] + } +} \ No newline at end of file Added: pkg/blotter/R/.Rproj.user/2C25DC80/pcs/files-pane.pper =================================================================== --- pkg/blotter/R/.Rproj.user/2C25DC80/pcs/files-pane.pper (rev 0) +++ pkg/blotter/R/.Rproj.user/2C25DC80/pcs/files-pane.pper 2016-04-02 22:37:35 UTC (rev 1742) @@ -0,0 +1,13 @@ +{ + "path" : "C:/Users/jasen/Personal/blotter/pkg/blotter/R", + "sortOrder" : [ + { + "ascending" : false, + "columnIndex" : 1 + }, + { + "ascending" : true, + "columnIndex" : 2 + } + ] +} \ No newline at end of file Added: pkg/blotter/R/.Rproj.user/2C25DC80/pcs/source-pane.pper =================================================================== --- pkg/blotter/R/.Rproj.user/2C25DC80/pcs/source-pane.pper (rev 0) +++ pkg/blotter/R/.Rproj.user/2C25DC80/pcs/source-pane.pper 2016-04-02 22:37:35 UTC (rev 1742) @@ -0,0 +1,3 @@ +{ + "activeTab" : 1 +} \ No newline at end of file Added: pkg/blotter/R/.Rproj.user/2C25DC80/pcs/windowlayoutstate.pper =================================================================== --- pkg/blotter/R/.Rproj.user/2C25DC80/pcs/windowlayoutstate.pper (rev 0) +++ pkg/blotter/R/.Rproj.user/2C25DC80/pcs/windowlayoutstate.pper 2016-04-02 22:37:35 UTC (rev 1742) @@ -0,0 +1,14 @@ +{ + "left" : { + "panelheight" : 1798, + "splitterpos" : 734, + "topwindowstate" : "NORMAL", + "windowheight" : 1836 + }, + "right" : { + "panelheight" : 1798, + "splitterpos" : 1101, + "topwindowstate" : "NORMAL", + "windowheight" : 1836 + } +} \ No newline at end of file Added: pkg/blotter/R/.Rproj.user/2C25DC80/pcs/workbench-pane.pper =================================================================== --- pkg/blotter/R/.Rproj.user/2C25DC80/pcs/workbench-pane.pper (rev 0) +++ pkg/blotter/R/.Rproj.user/2C25DC80/pcs/workbench-pane.pper 2016-04-02 22:37:35 UTC (rev 1742) @@ -0,0 +1,4 @@ +{ + "TabSet1" : 2, + "TabSet2" : 1 +} \ No newline at end of file Added: pkg/blotter/R/.Rproj.user/2C25DC80/persistent-state =================================================================== --- pkg/blotter/R/.Rproj.user/2C25DC80/persistent-state (rev 0) +++ pkg/blotter/R/.Rproj.user/2C25DC80/persistent-state 2016-04-02 22:37:35 UTC (rev 1742) @@ -0,0 +1,9 @@ +build-last-errors="[]" +build-last-errors-base-dir="C:/Users/jasen/Personal/blotter/pkg/blotter/" +build-last-outputs="[{\"output\":\"==> devtools::document(roclets=c('rd', 'collate', 'namespace'))\\n\\n\",\"type\":0},{\"output\":\"Updating blotter documentation\\r\\nLoading blotter\\r\\n\",\"type\":2},{\"output\":\"Writing AcctReturns.Rd\\r\\nWriting PortfReturns.Rd\\r\\nWriting addAcctTxn.Rd\\r\\nWriting addPortfInstr.Rd\\r\\nWriting addTxn.Rd\\r\\nWriting pennyPerShare.Rd\\r\\nWriting addDiv.Rd\\r\\n\",\"type\":1},{\"output\":\"Writing blotter-package.Rd\\r\\nWriting calcPortfWgt.Rd\\r\\nWriting calcPosAvgCost.Rd\\r\\nWriting calcTxnAvgCost.Rd\\r\\nWriting calcTxnValue.Rd\\r\\nWriting chart.ME.Rd\\r\\nWriting chart.Posn.Rd\\r\\nWriting chart.Reconcile.Rd\\r\\nWriting chart.Spread.Rd\\r\\nWriting extractTxns.Rd\\r\\nWriting getAccount.Rd\\r\\nWriting is.account.Rd\\r\\nWriting getByPortf.Rd\\r\\nWriting getBySymbol.Rd\\r\\nWriting getEndEq.Rd\\r\\nWriting getPortfAcct.Rd\\r\\nWriting getPortfolio.Rd\\r\\nWriting is.portfolio.Rd\\r\\nWriting getPos.Rd\\r\\nWriting getPosAvgCost.Rd\\r\\nWriting getPosQty.Rd\\r\\n\",\"type\":1},{\"output\":\"Writing getTxns.Rd\\r\\nWriting initAcct.Rd\\r\\nWriting initPortf.Rd\\r\\nWriting initPosPL.Rd\\r\\nWriting initSummary.Rd\\r\\nWriting initTxn.Rd\\r\\nWriting mcsim.Rd\\r\\nWriting perTradeStats.Rd\\r\\nWriting tradeQuantiles.Rd\\r\\nWriting put.account.Rd\\r\\nWriting put.portfolio.Rd\\r\\nWriting tradeStats.Rd\\r\\nWriting dailyTxnPL.Rd\\r\\nWriting updateAcct.Rd\\r\\nWriting updateEndEq.Rd\\r\\nWriting updatePortf.Rd\\r\\nWriting updatePosPL.Rd\\r\\n\",\"type\":1},{\"output\":\"Writing NAMESPACE\\r\\n\",\"type\":1},{\"output\":\"Documentation completed\\n\\n\",\"type\":1},{\"output\":\"==> Rcmd.exe INSTALL --no-multiarch --with-keep.source blotter\\n\\n\",\"type\":0},{\"output\":\"* installing to library 'C:/Users/jasen/Documents/R/win-library/3.2'\\r\\n\",\"type\":1},{\"output\":\"\",\"type\":1},{\"output\":\"* installing *source* package 'blotter' ...\\r\\n\",\"type\":1},{\"output\":\"\",\"type\":1},{\"output\":\"make: Nothing to be done for `all'.\\n\",\"type\":1},{\"output\":\"\",\"type\":1},{\"output\":\"** libs\\r\\n\",\"type\":1},{\"output\":\"installing to C:/Users/jasen/Documents/R/win-library/3.2/blotter/libs/x64\\r\\n\",\"type\":1},{\"output\":\"** R\\r\\n\",\"type\":1},{\"output\":\"\",\"type\":1},{\"output\":\"** data\\r\\n\",\"type\":1},{\"output\":\"** demo\\r\\n\",\"type\":1},{\"output\":\"** byte-compile and prepare package for lazy loading\\r\\n\",\"type\":1},{\"output\":\"\",\"type\":1},{\"output\":\"Note: no visible binding for '<<-' assignment to '.blotter' \\r\\n\",\"type\":1},{\"output\":\"\",\"type\":1},{\"output\":\"** help\\r\\n\",\"type\":1},{\"output\":\"\",\"type\":1},{\"output\":\"*** installing help indices\\r\\n\",\"type\":1},{\"output\":\"\",\"type\":1},{\"output\":\"** building package indices\\r\\n\",\"type\":1},{\"output\":\"\",\"type\":1},{\"output\":\"** testing if installed package can be loaded\\r\\n\",\"type\":1},{\"output\":\"\",\"type\":1},{\"output\":\"* DONE (blotter)\\r\\n\",\"type\":1},{\"output\":\"\",\"type\":1}]" +compile_pdf_state="{\"errors\":[],\"output\":\"\",\"running\":false,\"tab_visible\":false,\"target_file\":\"\"}" +console_procs="[]" +files.monitored-path="" +find-in-files-state="{\"handle\":\"\",\"input\":\"\",\"path\":\"\",\"regex\":true,\"results\":{\"file\":[],\"line\":[],\"lineValue\":[],\"matchOff\":[],\"matchOn\":[]},\"running\":false}" +imageDirtyState="1" +saveActionState="-1" Added: pkg/blotter/R/.Rproj.user/2C25DC80/saved_source_markers =================================================================== --- pkg/blotter/R/.Rproj.user/2C25DC80/saved_source_markers (rev 0) +++ pkg/blotter/R/.Rproj.user/2C25DC80/saved_source_markers 2016-04-02 22:37:35 UTC (rev 1742) @@ -0,0 +1 @@ +{"active_set":"","sets":[]} \ No newline at end of file Added: pkg/blotter/R/.Rproj.user/2C25DC80/sdb/prop/209001 =================================================================== --- pkg/blotter/R/.Rproj.user/2C25DC80/sdb/prop/209001 (rev 0) +++ pkg/blotter/R/.Rproj.user/2C25DC80/sdb/prop/209001 2016-04-02 22:37:35 UTC (rev 1742) @@ -0,0 +1,2 @@ +{ +} \ No newline at end of file Added: pkg/blotter/R/.Rproj.user/2C25DC80/sdb/prop/27FA44DF =================================================================== --- pkg/blotter/R/.Rproj.user/2C25DC80/sdb/prop/27FA44DF (rev 0) +++ pkg/blotter/R/.Rproj.user/2C25DC80/sdb/prop/27FA44DF 2016-04-02 22:37:35 UTC (rev 1742) @@ -0,0 +1,2 @@ +{ +} \ No newline at end of file Added: pkg/blotter/R/.Rproj.user/2C25DC80/sdb/prop/318E0CA1 =================================================================== --- pkg/blotter/R/.Rproj.user/2C25DC80/sdb/prop/318E0CA1 (rev 0) +++ pkg/blotter/R/.Rproj.user/2C25DC80/sdb/prop/318E0CA1 2016-04-02 22:37:35 UTC (rev 1742) @@ -0,0 +1,2 @@ +{ +} \ No newline at end of file Added: pkg/blotter/R/.Rproj.user/2C25DC80/sdb/prop/4E8BB848 =================================================================== --- pkg/blotter/R/.Rproj.user/2C25DC80/sdb/prop/4E8BB848 (rev 0) +++ pkg/blotter/R/.Rproj.user/2C25DC80/sdb/prop/4E8BB848 2016-04-02 22:37:35 UTC (rev 1742) @@ -0,0 +1,2 @@ +{ +} \ No newline at end of file Added: pkg/blotter/R/.Rproj.user/2C25DC80/sdb/prop/561640DF =================================================================== --- pkg/blotter/R/.Rproj.user/2C25DC80/sdb/prop/561640DF (rev 0) +++ pkg/blotter/R/.Rproj.user/2C25DC80/sdb/prop/561640DF 2016-04-02 22:37:35 UTC (rev 1742) @@ -0,0 +1,2 @@ +{ +} \ No newline at end of file Added: pkg/blotter/R/.Rproj.user/2C25DC80/sdb/prop/842BCF43 =================================================================== --- pkg/blotter/R/.Rproj.user/2C25DC80/sdb/prop/842BCF43 (rev 0) +++ pkg/blotter/R/.Rproj.user/2C25DC80/sdb/prop/842BCF43 2016-04-02 22:37:35 UTC (rev 1742) @@ -0,0 +1,3 @@ +{ + "tempName" : "Untitled1" +} \ No newline at end of file [TRUNCATED] To get the complete diff run: svnlook diff /svnroot/blotter -r 1742 From noreply at r-forge.r-project.org Sun Apr 3 00:45:39 2016 From: noreply at r-forge.r-project.org (noreply at r-forge.r-project.org) Date: Sun, 3 Apr 2016 00:45:39 +0200 (CEST) Subject: [Blotter-commits] r1743 - pkg/blotter/R Message-ID: <20160402224539.5FD7B188088@r-forge.r-project.org> Author: bodanker Date: 2016-04-03 00:45:38 +0200 (Sun, 03 Apr 2016) New Revision: 1743 Removed: pkg/blotter/R/.Rhistory pkg/blotter/R/.Rproj.user/ pkg/blotter/R/R.Rproj Log: Remove unnecessary user files Deleted: pkg/blotter/R/.Rhistory =================================================================== --- pkg/blotter/R/.Rhistory 2016-04-02 22:37:35 UTC (rev 1742) +++ pkg/blotter/R/.Rhistory 2016-04-02 22:45:38 UTC (rev 1743) @@ -1,512 +0,0 @@ -is.na(ret[-1,]) -any(is.na(ret[-1,])) -plot(ret) -plot(cumsum(ret)) -ret <- ROC(EndEq) -h <- ggplot(charts, aes(x = index(charts))) + -geom_ribbon(aes(ymin = ret_25, ymax = ret_75, colour = "50%"), alpha = 0.3, fill = "red3") + -geom_ribbon(aes(ymin = ret_5, ymax = ret_95, colour = "90%"), alpha = 0.3, fill = "cornflowerblue") + -theme(axis.text.x = element_text(angle=0, hjust = 0), -axis.title = element_text(face = 'bold', size = 14), -title = element_text(face = 'bold', size = 16), -legend.position = 'bottom', -legend.title = element_blank(), -legend.text = element_text(size = 12), -legend.key.width = unit(2, 'cm')) -h <- h + geom_line(aes(y = cumsum(ret[-1,])), colour = "black", linetype = 1) + -ylab(label="Cumulative Returns") + -xlab(label="Time") + -ggtitle("Returns Distribution") -print(h) -EndEq -ROC(EndEq) -plot(ROC(EndEq)) -class(ret) -#Version 4 -#playing with graphs and shading and legend -t1 <- Sys.time() -# Attach packages. You can install packages via: -# install.packages(c("quantmod","TTR","PerformanceAnalytics")) -library(quantmod) -library(TTR) -library(PerformanceAnalytics) -library(ggplot2) -library(timeSeries) -#Read price data and build xts object -data <- read.csv("C:/Users/jasen/Work/R/simSample.csv", header = TRUE, stringsAsFactors=F) -s1.dates <- as.Date(data[,2], format="%d-%m-%Y") -s1 <- xts(data[,3], s1.dates) -#Calculate ROC -ret <- ROC(s1[,1]) -#Chart cum returns -chart.CumReturns(ret) -#Set up for Sample() and Replicate() -n <- 10000 #number of replications -b <- TRUE #Sample with/without Replacement (Boolean) -ret_sample <- replicate(n,sample(as.vector(ret[-1,]), replace=b)) #use ret[-1] so we exclude 1st NA value from ROC calc -ret_cum_sample <- apply(ret_sample, 2, function(x) cumsum(x)) -ret_cum_samplexts <- xts(ret_cum_sample, s1.dates[-1]) #use s1.dates[-1] so that length of dates is identical to length of ret_sample -#Build the 5% and 95% quantile datasets -ret_5 <- apply(ret_cum_samplexts, 1, function(x) quantile(x, .05)) -ret_5 <- as.xts(ret_5) -ret_95 <- apply(ret_cum_samplexts, 1, function(x) quantile(x, .95)) -ret_95 <- as.xts(ret_95) -ret_25 <- apply(ret_cum_samplexts, 1, function(x) quantile(x, .25)) -ret_25 <- as.xts(ret_25) -ret_75 <- apply(ret_cum_samplexts, 1, function(x) quantile(x, .75)) -ret_75 <- as.xts(ret_75) -charts <- merge(ret_5, ret_95, ret_25, ret_75) -#lets try some shading -h <- ggplot(charts, aes(x = index(charts))) + -geom_ribbon(aes(ymin = ret_25, ymax = ret_75, colour = "50%"), alpha = 0.3, fill = "red3") + -geom_ribbon(aes(ymin = ret_5, ymax = ret_95, colour = "90%"), alpha = 0.3, fill = "cornflowerblue") + -theme(axis.text.x = element_text(angle=0, hjust = 0), -axis.title = element_text(face = 'bold', size = 14), -title = element_text(face = 'bold', size = 16), -legend.position = 'bottom', -legend.title = element_blank(), -legend.text = element_text(size = 12), -legend.key.width = unit(2, 'cm')) -h <- h + geom_line(aes(y = cumsum(ret[-1,])), colour = "black", linetype = 1) + -ylab(label="Cumulative Returns") + -xlab(label="Time") + -ggtitle("Returns Distribution") -h -t2 <- Sys.time() -difftime(t2,t1) -class(ret) -a <- getAccount(Account) -EndEq <- a$summary$End.Eq -a$summary -# Draw the graph with a ribbon -h <- ggplot(charts, aes(x = index(charts))) + -geom_ribbon(aes(ymin = ret_25, ymax = ret_75, colour = "50%"), alpha = 0.3, fill = "red3") + -geom_ribbon(aes(ymin = ret_5, ymax = ret_95, colour = "90%"), alpha = 0.3, fill = "cornflowerblue") + -theme(axis.text.x = element_text(angle=0, hjust = 0), -axis.title = element_text(face = 'bold', size = 14), -title = element_text(face = 'bold', size = 16), -legend.position = 'bottom', -legend.title = element_blank(), -legend.text = element_text(size = 12), -legend.key.width = unit(2, 'cm')) -#h <- h + geom_line(aes(y = cumsum(ret[-1,])), colour = "black", linetype = 1) + -h <- h + geom_line(aes(y = EndEq[-1,])), colour = "black", linetype = 1) + -ylab(label="Cumulative Returns") + -xlab(label="Time") + -ggtitle("Returns Distribution") -h -EndEq -class(EndEq) -# Draw the graph with a ribbon -h <- ggplot(charts, aes(x = index(charts))) + -geom_ribbon(aes(ymin = ret_25, ymax = ret_75, colour = "50%"), alpha = 0.3, fill = "red3") + -geom_ribbon(aes(ymin = ret_5, ymax = ret_95, colour = "90%"), alpha = 0.3, fill = "cornflowerblue") + -theme(axis.text.x = element_text(angle=0, hjust = 0), -axis.title = element_text(face = 'bold', size = 14), -title = element_text(face = 'bold', size = 16), -legend.position = 'bottom', -legend.title = element_blank(), -legend.text = element_text(size = 12), -legend.key.width = unit(2, 'cm')) -#h <- h + geom_line(aes(y = cumsum(ret[-1,])), colour = "black", linetype = 1) + -h <- h + #geom_line(aes(y = EndEq[-1,])), colour = "black", linetype = 1) + -ylab(label="Cumulative Returns") + -xlab(label="Time") + -ggtitle("Returns Distribution") -h -#' Retrieves the most recent value of the capital account -#' @param Account string identifier of account -#' @param n number of monte carlo simulations -#' @return Graph ggplot of simulations -# Build the function ---------------------------------------------- -mcsimr <- function(Account, n, Replace = TRUE){ -aname<-Account -Account<-try(get(paste("account",aname,sep='.'), envir=.blotter), silent=TRUE) -if(inherits(Account,"try-error")) -stop("Account ", aname, " not found, use initAcct() to create a new account") -a <- getAccount(Account) -EndEq <- a$summary$End.Eq -# # Read price data and build xts object -# data <- read.csv("simSample.csv", header = TRUE, stringsAsFactors=F) -# s1.dates <- as.Date(data[,2], format="%d-%m-%Y") -s1.dates <- index(a$summary) -# s1 <- xts(data[,3], s1.dates) -# Calculate ROC -ret <- ROC(EndEq) -# Chart cum returns -chart.CumReturns(ret) -# Set up for Sample() and Replicate() -ret_sample <- replicate(n,sample(as.vector(ret[-1,]), replace=Replace)) #use ret[-1] so we exclude 1st NA value from ROC calc -ret_cum_sample <- apply(ret_sample, 2, function(x) cumsum(x)) -ret_cum_samplexts <- xts(ret_cum_sample, s1.dates[-1]) #use s1.dates[-1] so that length of dates is identical to length of ret_sample -# Build the 5% and 95% quantile datasets -ret_5 <- apply(ret_cum_samplexts, 1, function(x) quantile(x, .05)) -ret_5 <- as.xts(ret_5) -ret_95 <- apply(ret_cum_samplexts, 1, function(x) quantile(x, .95)) -ret_95 <- as.xts(ret_95) -ret_25 <- apply(ret_cum_samplexts, 1, function(x) quantile(x, .25)) -ret_25 <- as.xts(ret_25) -ret_75 <- apply(ret_cum_samplexts, 1, function(x) quantile(x, .75)) -ret_75 <- as.xts(ret_75) -charts <- merge(ret_5, ret_95, ret_25, ret_75) -# Draw the graph with a ribbon -h <- ggplot(charts, aes(x = index(charts))) + -geom_ribbon(aes(ymin = ret_25, ymax = ret_75, colour = "50%"), alpha = 0.3, fill = "red3") + -geom_ribbon(aes(ymin = ret_5, ymax = ret_95, colour = "90%"), alpha = 0.3, fill = "cornflowerblue") + -theme(axis.text.x = element_text(angle=0, hjust = 0), -axis.title = element_text(face = 'bold', size = 14), -title = element_text(face = 'bold', size = 16), -legend.position = 'bottom', -legend.title = element_blank(), -legend.text = element_text(size = 12), -legend.key.width = unit(2, 'cm')) -#h <- h + geom_line(aes(y = cumsum(ret[-1,])), colour = "black", linetype = 1) + -h <- h + #geom_line(aes(y = EndEq[-1,])), colour = "black", linetype = 1) + -ylab(label="Cumulative Returns") + -xlab(label="Time") + -ggtitle("Returns Distribution") -h -return(h) -} -# Build the function ---------------------------------------------- -mcsim <- function(Account, n, Replace = TRUE){ -aname<-Account -Account<-try(get(paste("account",aname,sep='.'), envir=.blotter), silent=TRUE) -if(inherits(Account,"try-error")) -stop("Account ", aname, " not found, use initAcct() to create a new account") -a <- getAccount(Account) -EndEq <- a$summary$End.Eq -# # Read price data and build xts object -# data <- read.csv("simSample.csv", header = TRUE, stringsAsFactors=F) -# s1.dates <- as.Date(data[,2], format="%d-%m-%Y") -s1.dates <- index(a$summary) -# s1 <- xts(data[,3], s1.dates) -# Calculate ROC -ret <- ROC(EndEq) -# Chart cum returns -chart.CumReturns(ret) -# Set up for Sample() and Replicate() -ret_sample <- replicate(n,sample(as.vector(ret[-1,]), replace=Replace)) #use ret[-1] so we exclude 1st NA value from ROC calc -ret_cum_sample <- apply(ret_sample, 2, function(x) cumsum(x)) -ret_cum_samplexts <- xts(ret_cum_sample, s1.dates[-1]) #use s1.dates[-1] so that length of dates is identical to length of ret_sample -# Build the 5% and 95% quantile datasets -ret_5 <- apply(ret_cum_samplexts, 1, function(x) quantile(x, .05)) -ret_5 <- as.xts(ret_5) -ret_95 <- apply(ret_cum_samplexts, 1, function(x) quantile(x, .95)) -ret_95 <- as.xts(ret_95) -ret_25 <- apply(ret_cum_samplexts, 1, function(x) quantile(x, .25)) -ret_25 <- as.xts(ret_25) -ret_75 <- apply(ret_cum_samplexts, 1, function(x) quantile(x, .75)) -ret_75 <- as.xts(ret_75) -charts <- merge(ret_5, ret_95, ret_25, ret_75) -# Draw the graph with a ribbon -h <- ggplot(charts, aes(x = index(charts))) + -geom_ribbon(aes(ymin = ret_25, ymax = ret_75, colour = "50%"), alpha = 0.3, fill = "red3") + -geom_ribbon(aes(ymin = ret_5, ymax = ret_95, colour = "90%"), alpha = 0.3, fill = "cornflowerblue") + -theme(axis.text.x = element_text(angle=0, hjust = 0), -axis.title = element_text(face = 'bold', size = 14), -title = element_text(face = 'bold', size = 16), -legend.position = 'bottom', -legend.title = element_blank(), -legend.text = element_text(size = 12), -legend.key.width = unit(2, 'cm')) -#h <- h + geom_line(aes(y = cumsum(ret[-1,])), colour = "black", linetype = 1) + -h <- h + #geom_line(aes(y = EndEq[-1,])), colour = "black", linetype = 1) + -ylab(label="Cumulative Returns") + -xlab(label="Time") + -ggtitle("Returns Distribution") -h -return(h) -} -mcsimr("longtrend", 10000,) -mcsim("longtrend", 10000,TRUE) -# This is a very simple trend following strategy for testing the results of: -# Faber, Mebane T., "A Quantitative Approach to Tactical Asset Allocation." -# Journal of Risk Management (Spring 2007). -# The article proposes a very simple quantitative market-timing model. They -# test the model in sample on the US stock market since 1900 before testing -# it out-of-sample in twenty other markets. -# The article discusses a 200-day simple moving average, which is proposed -# in Jeremy Seigel's book "Stocks for the Long Run" for timing the DJIA. He -# concludes that a simple market timing strategy improves the absolute and -# risk adjusted returns over a buy-and-hold strategy. After all transaction -# costs are included, the timing strategy falls short on the absolute return, -# but still provides a better risk-adjusted return. Siegel also tests timing on -# the Nasdaq composite since 1972 and finds better absolute and risk adjusted -# returns. -# The article implements a simpler version of the 200-day SMA, opting for a -# 10-month SMA. Monthly data is more easily available for long periods of time, -# and the lower granularity should translate to lower transaction costs. -# The rules of the system are relatively simple: -# - Buy when monthly price > 10-month SMA -# - Sell and move to cash when monthly price < 10-month SMA -# 1. All entry and exit prices are on the day of the signal at the close. -# 2. All data series are total return series including dividends, updated monthly. -# For the purposes of this demo, we only use price returns. -# 3. Cash returns are estimated with 90-day commercial paper. Margin rates for -# leveraged models are estimated with the broker call rate. Again, for the -# purposes of this demo, we ignore interest and leverage. -# 4. Taxes, commissions, and slippage are excluded. -# This simple strategy is different from well-known trend-following systems in -# three respects. First, there's no shorting. Positions are converted to cash on -# a 'sell' signal, rather than taking a short position. Second, the entire position -# is put on at trade inception. No assumptions are made about increasing position -# size as the trend progresses. Third, there are no stops. If the trend reverts -# quickly, this system will wait for a sell signal before selling the position. -# Data -# Instead of using total returns data, this demo uses monthly data for the SP500 -# downloaded from Yahoo Finance. We'll use about 10 years of data, starting at -# the beginning of 1998. -# Load required libraries -require(quantmod) -require(TTR) -require(blotter) -Sys.setenv(TZ="UTC") -# Try to clean up in case the demo was run previously -try(rm("account.longtrend","portfolio.longtrend",pos=.blotter),silent=TRUE) -try(rm("ltaccount","ltportfolio","ClosePrice","CurrentDate","equity","GSPC","i","initDate","initEq","Posn","UnitSize","verbose"),silent=TRUE) -# Set initial values -initDate='1997-12-31' -initEq=100000 -# Load data with quantmod -print("Loading data") -currency("USD") -stock("GSPC",currency="USD",multiplier=1) -getSymbols('^GSPC', src='yahoo', index.class=c("POSIXt","POSIXct"),from='1998-01-01') -GSPC=to.monthly(GSPC, indexAt='endof', drop.time=FALSE) -# Set up indicators with TTR -print("Setting up indicators") -GSPC$SMA10m <- SMA(GSPC[,grep('Adj',colnames(GSPC))], 10) -# Set up a portfolio object and an account object in blotter -print("Initializing portfolio and account structure") -ltportfolio='longtrend' -ltaccount='longtrend' -initPortf(ltportfolio,'GSPC', initDate=initDate) -initAcct(ltaccount,portfolios='longtrend', initDate=initDate, initEq=initEq) -verbose=TRUE -# Create trades -for( i in 10:NROW(GSPC) ) { -# browser() -CurrentDate=time(GSPC)[i] -cat(".") -equity = getEndEq(ltaccount, CurrentDate) -ClosePrice = as.numeric(Ad(GSPC[i,])) -Posn = getPosQty(ltportfolio, Symbol='GSPC', Date=CurrentDate) -UnitSize = as.numeric(trunc(equity/ClosePrice)) -# Position Entry (assume fill at close) -if( Posn == 0 ) { -# No position, so test to initiate Long position -if( as.numeric(Ad(GSPC[i,])) > as.numeric(GSPC[i,'SMA10m']) ) { -cat('\n') -# Store trade with blotter -addTxn(ltportfolio, Symbol='GSPC', TxnDate=CurrentDate, TxnPrice=ClosePrice, TxnQty = UnitSize , TxnFees=0, verbose=verbose) -} -} else { -# Have a position, so check exit -if( as.numeric(Ad(GSPC[i,])) < as.numeric(GSPC[i,'SMA10m'])) { -cat('\n') -# Store trade with blotter -addTxn(ltportfolio, Symbol='GSPC', TxnDate=CurrentDate, TxnPrice=ClosePrice, TxnQty = -Posn , TxnFees=0, verbose=verbose) -} -} -# Calculate P&L and resulting equity with blotter -updatePortf(ltportfolio, Dates = CurrentDate) -updateAcct(ltaccount, Dates = CurrentDate) -updateEndEq(ltaccount, Dates = CurrentDate) -} # End dates loop -cat('\n') -# Chart results with quantmod -chart.Posn(ltportfolio, Symbol = 'GSPC', Dates = '1998::') -plot(add_SMA(n=10,col='darkgreen', on=1)) -#look at a transaction summary -getTxns(Portfolio="longtrend", Symbol="GSPC") -# Copy the results into the local environment -print("Retrieving resulting portfolio and account") -ltportfolio = getPortfolio("longtrend") -ltaccount = getAccount("longtrend") -############################################################################### -# Blotter: Tools for transaction-oriented trading systems development -# for R (see http://r-project.org/) -# Copyright (c) 2008 Peter Carl and Brian G. Peterson -# -# This library is distributed under the terms of the GNU Public License (GPL) -# for full details see the file COPYING -# -# $Id: longtrend.R 1483 2013-07-22 01:27:14Z bodanker $ -# -############################################################################### -# Build the function ---------------------------------------------- -mcsim <- function(Account, n, Replace = TRUE){ -aname<-Account -Account<-try(get(paste("account",aname,sep='.'), envir=.blotter), silent=TRUE) -if(inherits(Account,"try-error")) -stop("Account ", aname, " not found, use initAcct() to create a new account") -a <- getAccount(Account) -EndEq <- a$summary$End.Eq -# # Read price data and build xts object -# data <- read.csv("simSample.csv", header = TRUE, stringsAsFactors=F) -# s1.dates <- as.Date(data[,2], format="%d-%m-%Y") -s1.dates <- index(a$summary) -# s1 <- xts(data[,3], s1.dates) -# Calculate ROC -ret <- ROC(EndEq) -# Chart cum returns -chart.CumReturns(ret) -# Set up for Sample() and Replicate() -ret_sample <- replicate(n,sample(as.vector(ret[-1,]), replace=Replace)) #use ret[-1] so we exclude 1st NA value from ROC calc -ret_cum_sample <- apply(ret_sample, 2, function(x) cumsum(x)) -ret_cum_samplexts <- xts(ret_cum_sample, s1.dates[-1]) #use s1.dates[-1] so that length of dates is identical to length of ret_sample -# Build the 5% and 95% quantile datasets -ret_5 <- apply(ret_cum_samplexts, 1, function(x) quantile(x, .05)) -ret_5 <- as.xts(ret_5) -ret_95 <- apply(ret_cum_samplexts, 1, function(x) quantile(x, .95)) -ret_95 <- as.xts(ret_95) -ret_25 <- apply(ret_cum_samplexts, 1, function(x) quantile(x, .25)) -ret_25 <- as.xts(ret_25) -ret_75 <- apply(ret_cum_samplexts, 1, function(x) quantile(x, .75)) -ret_75 <- as.xts(ret_75) -charts <- merge(ret_5, ret_95, ret_25, ret_75) -# Draw the graph with a ribbon -h <- ggplot(charts, aes(x = index(charts))) + -geom_ribbon(aes(ymin = ret_25, ymax = ret_75, colour = "50%"), alpha = 0.3, fill = "red3") + -geom_ribbon(aes(ymin = ret_5, ymax = ret_95, colour = "90%"), alpha = 0.3, fill = "cornflowerblue") + -theme(axis.text.x = element_text(angle=0, hjust = 0), -axis.title = element_text(face = 'bold', size = 14), -title = element_text(face = 'bold', size = 16), -legend.position = 'bottom', -legend.title = element_blank(), -legend.text = element_text(size = 12), -legend.key.width = unit(2, 'cm')) -#h <- h + geom_line(aes(y = cumsum(ret[-1,])), colour = "black", linetype = 1) + -h <- h + #geom_line(aes(y = EndEq[-1,])), colour = "black", linetype = 1) + -ylab(label="Cumulative Returns") + -xlab(label="Time") + -ggtitle("Returns Distribution") -h -return(h) -} -mcsim("longtrend", 10000,TRUE) -Account <- "longtrend" -a <- getAccount(Account) -EndEq <- a$summary$End.Eq -View(EndEq) -s1.dates <- index(a$summary) -ret <- ROC(EndEq) -# Chart cum returns -chart.CumReturns(ret) -# Set up for Sample() and Replicate() -ret_sample <- replicate(n,sample(as.vector(ret[-1,]), replace=Replace)) #use ret[-1] so we exclude 1st NA value from ROC calc -ret_cum_sample <- apply(ret_sample, 2, function(x) cumsum(x)) -ret_cum_samplexts <- xts(ret_cum_sample, s1.dates[-1]) #use s1.dates[-1] so that length of dates is identical to length of ret_sample -# Build the 5% and 95% quantile datasets -ret_5 <- apply(ret_cum_samplexts, 1, function(x) quantile(x, .05)) -n <- 100 -ret_sample <- replicate(n,sample(as.vector(ret[-1,]), replace=Replace)) #use ret[-1] so we exclude 1st NA value from ROC calc -Replace = TRUE -ret_sample <- replicate(n,sample(as.vector(ret[-1,]), replace=Replace)) #use ret[-1] so we exclude 1st NA value from ROC calc -ret_cum_sample <- apply(ret_sample, 2, function(x) cumsum(x)) -ret_cum_samplexts <- xts(ret_cum_sample, s1.dates[-1]) #use s1.dates[-1] so that length of dates is identical to length of ret_sample -# Build the 5% and 95% quantile datasets -ret_5 <- apply(ret_cum_samplexts, 1, function(x) quantile(x, .05)) -ret_5 <- as.xts(ret_5) -ret_95 <- apply(ret_cum_samplexts, 1, function(x) quantile(x, .95)) -ret_95 <- as.xts(ret_95) -ret_25 <- apply(ret_cum_samplexts, 1, function(x) quantile(x, .25)) -ret_25 <- as.xts(ret_25) -ret_75 <- apply(ret_cum_samplexts, 1, function(x) quantile(x, .75)) -ret_75 <- as.xts(ret_75) -charts <- merge(ret_5, ret_95, ret_25, ret_75) -# Draw the graph with a ribbon -h <- ggplot(charts, aes(x = index(charts))) + -geom_ribbon(aes(ymin = ret_25, ymax = ret_75, colour = "50%"), alpha = 0.3, fill = "red3") + -geom_ribbon(aes(ymin = ret_5, ymax = ret_95, colour = "90%"), alpha = 0.3, fill = "cornflowerblue") + -theme(axis.text.x = element_text(angle=0, hjust = 0), -axis.title = element_text(face = 'bold', size = 14), -title = element_text(face = 'bold', size = 16), -legend.position = 'bottom', -legend.title = element_blank(), -legend.text = element_text(size = 12), -legend.key.width = unit(2, 'cm')) -#h <- h + geom_line(aes(y = cumsum(ret[-1,])), colour = "black", linetype = 1) + -h <- h + #geom_line(aes(y = EndEq[-1,])), colour = "black", linetype = 1) + -ylab(label="Cumulative Returns") + -xlab(label="Time") + -ggtitle("Returns Distribution") -h -return(h) -mcsim("longtrend", 100, TRUE) -aname<-Account -Account<-try(get(paste("account",aname,sep='.'), envir=.blotter), silent=TRUE) -if(inherits(Account,"try-error")) -stop("Account ", aname, " not found, use initAcct() to create a new account") -mcsim <- function(Account, n = 100, Replace = TRUE){ -# aname<-Account -# Account<-try(get(paste("account",aname,sep='.'), envir=.blotter), silent=TRUE) -# if(inherits(Account,"try-error")) -# stop("Account ", aname, " not found, use initAcct() to create a new account") -# -a <- getAccount(Account) -EndEq <- a$summary$End.Eq -# # Read price data and build xts object -# data <- read.csv("simSample.csv", header = TRUE, stringsAsFactors=F) -# s1.dates <- as.Date(data[,2], format="%d-%m-%Y") -s1.dates <- index(a$summary) -# s1 <- xts(data[,3], s1.dates) -# Calculate ROC -ret <- ROC(EndEq) -# Chart cum returns -chart.CumReturns(ret) -# Set up for Sample() and Replicate() -ret_sample <- replicate(n,sample(as.vector(ret[-1,]), replace=Replace)) #use ret[-1] so we exclude 1st NA value from ROC calc -ret_cum_sample <- apply(ret_sample, 2, function(x) cumsum(x)) -ret_cum_samplexts <- xts(ret_cum_sample, s1.dates[-1]) #use s1.dates[-1] so that length of dates is identical to length of ret_sample -# Build the 5% and 95% quantile datasets -ret_5 <- apply(ret_cum_samplexts, 1, function(x) quantile(x, .05)) -ret_5 <- as.xts(ret_5) -ret_95 <- apply(ret_cum_samplexts, 1, function(x) quantile(x, .95)) -ret_95 <- as.xts(ret_95) -ret_25 <- apply(ret_cum_samplexts, 1, function(x) quantile(x, .25)) -ret_25 <- as.xts(ret_25) -ret_75 <- apply(ret_cum_samplexts, 1, function(x) quantile(x, .75)) -ret_75 <- as.xts(ret_75) -charts <- merge(ret_5, ret_95, ret_25, ret_75) -# Draw the graph with a ribbon -h <- ggplot(charts, aes(x = index(charts))) + -geom_ribbon(aes(ymin = ret_25, ymax = ret_75, colour = "50%"), alpha = 0.3, fill = "red3") + -geom_ribbon(aes(ymin = ret_5, ymax = ret_95, colour = "90%"), alpha = 0.3, fill = "cornflowerblue") + -theme(axis.text.x = element_text(angle=0, hjust = 0), -axis.title = element_text(face = 'bold', size = 14), -title = element_text(face = 'bold', size = 16), -legend.position = 'bottom', -legend.title = element_blank(), -legend.text = element_text(size = 12), -legend.key.width = unit(2, 'cm')) -#h <- h + geom_line(aes(y = cumsum(ret[-1,])), colour = "black", linetype = 1) + -h <- h + #geom_line(aes(y = EndEq[-1,])), colour = "black", linetype = 1) + -ylab(label="Cumulative Returns") + -xlab(label="Time") + -ggtitle("Returns Distribution") -#h -return(h) -} -mcsim("longtrend", 100, TRUE) -load_all() -require(devtools) -load_all() -require(roxygen2) -load_all() -require(devtools) -load_all() -getwd() -require(roxygen2) -devtools::load_all(".") -devtools::load_all(".") -load_all() -install.packages("Rtools") -R CMD check blotter -R CMD check -R CMD check "blotter" -dev_tools::load_all -require(devtools) -devtools::load_all -devtools::load_all() Deleted: pkg/blotter/R/R.Rproj =================================================================== --- pkg/blotter/R/R.Rproj 2016-04-02 22:37:35 UTC (rev 1742) +++ pkg/blotter/R/R.Rproj 2016-04-02 22:45:38 UTC (rev 1743) @@ -1,19 +0,0 @@ -Version: 1.0 - -RestoreWorkspace: Default -SaveWorkspace: Default -AlwaysSaveHistory: Default - -EnableCodeIndexing: Yes -UseSpacesForTab: Yes -NumSpacesForTab: 2 -Encoding: UTF-8 - -RnwWeave: Sweave -LaTeX: pdfLaTeX - -BuildType: Package -PackageUseDevtools: Yes -PackagePath: C:/Users/jasen/Personal/blotter/pkg/blotter -PackageInstallArgs: --no-multiarch --with-keep.source -PackageRoxygenize: rd,collate,namespace From noreply at r-forge.r-project.org Sun Apr 3 16:22:29 2016 From: noreply at r-forge.r-project.org (noreply at r-forge.r-project.org) Date: Sun, 3 Apr 2016 16:22:29 +0200 (CEST) Subject: [Blotter-commits] r1744 - pkg/blotter/R Message-ID: <20160403142229.9963F187D43@r-forge.r-project.org> Author: jaymon0703 Date: 2016-04-03 16:22:28 +0200 (Sun, 03 Apr 2016) New Revision: 1744 Modified: pkg/blotter/R/mcsim.R Log: Modified: pkg/blotter/R/mcsim.R =================================================================== --- pkg/blotter/R/mcsim.R 2016-04-02 22:45:38 UTC (rev 1743) +++ pkg/blotter/R/mcsim.R 2016-04-03 14:22:28 UTC (rev 1744) @@ -1,7 +1,9 @@ -#' Retrieves the most recent value of the capital account +#' Monte Carlo simulate strategy results +#' +#' Return bands of returns based on Monte Carlo simulations of back-test results #' @param Account string identifier of account #' @param n number of monte carlo simulations -#' @param Replace boolean for sampling with or without replacement DEFAULT = TRUE +#' @param Replace boolean for sampling with or without replacement, default = TRUE #' @return a ggplot object of simulation bands #' @note #' Requires ggplot2 package @@ -9,7 +11,7 @@ #' @author Jasen Mackie, Brian G. Peterson #' @seealso \code{\link{ggplot}} -mcsim <- function(Account, n = 100, Replace = TRUE){ +mcsim <- function(Account, n, Replace = TRUE){ a <- getAccount(Account) EndEq <- a$summary$End.Eq From noreply at r-forge.r-project.org Sun Apr 3 16:50:15 2016 From: noreply at r-forge.r-project.org (noreply at r-forge.r-project.org) Date: Sun, 3 Apr 2016 16:50:15 +0200 (CEST) Subject: [Blotter-commits] r1745 - pkg/quantstrat/R Message-ID: <20160403145015.2250E188087@r-forge.r-project.org> Author: bodanker Date: 2016-04-03 16:50:14 +0200 (Sun, 03 Apr 2016) New Revision: 1745 Modified: pkg/quantstrat/R/indicators.R pkg/quantstrat/R/initialize.R pkg/quantstrat/R/rules.R pkg/quantstrat/R/signals.R pkg/quantstrat/R/wrapup.R Log: More robust function search (fixes #6310) get() throws an error if it cannot find an object, and it's possible it may find a non-function object in the search path before the function with the same name. Update all the places we search for functions by name by using the following strategy: Check if input argument is a function. If it is, set Fun object to input argument. Othewise use exists() to see if a function of that name can be found. If we can find a function, assign it to Fun using get(). Then use do.call() on Fun object to avoid another search. If we can't find a function, write a message and stop processing. Modified: pkg/quantstrat/R/indicators.R =================================================================== --- pkg/quantstrat/R/indicators.R 2016-04-03 14:22:28 UTC (rev 1744) +++ pkg/quantstrat/R/indicators.R 2016-04-03 14:50:14 UTC (rev 1745) @@ -163,15 +163,24 @@ mktdata <- mktdata[, keep] for (indicator in strategy$indicators){ - if(!is.function(get(indicator$name))){ - if(!is.function(get(paste("sig",indicator$name,sep='.')))){ - message(paste("Skipping indicator",indicator$name,"because there is no function by that name to call")) - next() + if(is.function(indicator$name)) { + indFun <- indicator$name + } else { + if(exists(indicator$name, mode="function")) { + indFun <- get(indicator$name, mode="function") } else { - indicator$name<-paste("ind",indicator$name,sep='.') + ind.name <- paste("ind", indicator$name, sep=".") + if(exists(ind.name, mode="function")) { + indFun <- get(ind.name, mode="function") + indicator$name <- ind.name + } else { + message("Skipping indicator ", indicator$name, + " because there is no function by that name to call") + next + } } } - + if(!isTRUE(indicator$enabled)) next() # replace default function arguments with indicator$arguments @@ -184,7 +193,7 @@ # remove ... to avoid matching multiple args .formals$`...` <- NULL - tmp_val <- do.call(indicator$name, .formals) + tmp_val <- do.call(indFun, .formals) #add label if(is.null(colnames(tmp_val))) Modified: pkg/quantstrat/R/initialize.R =================================================================== --- pkg/quantstrat/R/initialize.R 2016-04-03 14:22:28 UTC (rev 1744) +++ pkg/quantstrat/R/initialize.R 2016-04-03 14:50:14 UTC (rev 1745) @@ -97,11 +97,18 @@ # arbitrary user-defined initialization functions added to the initialization steps # now do whatever else the user stuck in this init slot... for (init_o in strategy$init){ - if(!is.function(get(init_o$name))){ - message(paste("Skipping initialization function",init_o$name,"because there is no function by that name to call")) - next() + if(is.function(init_o$name)) { + init_oFun <- init_o$name + } else { + if(exists(init_o$name, mode="function")) { + init_oFun <- get(init_o$name, mode="function") + } else { + message("Skipping initialization function ", init_o$name, + " because there is no function by that name to call.") + next + } } - + if(!isTRUE(init_o$enabled)) next() # replace default function arguments with init_o$arguments @@ -114,7 +121,7 @@ # remove ... to avoid matching multiple args .formals$`...` <- NULL - do.call(init_o$name, .formals) + do.call(init_oFun, .formals) } } @@ -193,15 +200,22 @@ ## run user-defined initialization function contained in the strategy slot init_symbol init_s <- strategy$init_symbol - if(!is.function(get(init_s$name))){ - message(paste("Iniziatialization function", init_s$name, "not found. Skipping")) - return() + + if(is.function(init_s$name)) { + init_sFun <- init_s$name + } else { + if(exists(init_s$name, mode="function")) { + init_sFun <- get(init_s$name, mode="function") + } else { + message("Initialization function ", init_s$name, " not found. Skipping") + return() + } } if(!isTRUE(init_s$enabled)) next() ## (from initStrategy) - ## replace default function arguments with init_o$arguments + ## replace default function arguments with init_s$arguments .formals <- formals(init_s$name) .formals <- modify.args(.formals, init_s$arguments, dots=TRUE) ## now add dots @@ -209,7 +223,7 @@ ## remove ... to avoid matching multiple args .formals$`...` <- NULL - do.call(init_s$name, .formals) + do.call(init_sFun, .formals) } Modified: pkg/quantstrat/R/rules.R =================================================================== --- pkg/quantstrat/R/rules.R 2016-04-03 14:22:28 UTC (rev 1744) +++ pkg/quantstrat/R/rules.R 2016-04-03 14:50:14 UTC (rev 1745) @@ -87,15 +87,19 @@ if(is.na(charmatch(type,c("risk","order","rebalance","exit","enter","chain","pre","post")))) stop(paste("type:",type,' must be one of "risk", "order", "rebalance", "exit", "enter", "chain", "pre", or "post"')) tmp_rule<-list() if(!is.function(name) && isTRUE(storefun)) { - if(!is.function(get(name))){ - if(!is.function(get(paste("rule",name,sep='.')))){ - message(paste("Skipping rule",name,"because there is no function by that name to call")) - next() + if(exists(name, mode="function")) { + fn <- get(name, mode="function") + } else { + rule.name <- paste("rule", name, sep=".") + if(exists(rule.name, mode="function")) { + fn <- get(rule.name, mode="function") + name <- rule.name } else { - name<-paste("rule",rule$name,sep='.') + message("Skipping rule ", name, + " because there is no function by that name to call") + next } } - fn<-match.fun(name) } else { fn <- name } @@ -653,17 +657,25 @@ for (rule in ruletypelist){ #TODO check to see if they've already been calculated if (!rule$path.dep==path.dep) next() - if(!is.function(rule$name)) { - if(!is.function(get(rule$name))){ - if(!is.function(get(paste("rule",rule$name,sep='.')))){ - message(paste("Skipping rule",rule$name,"because there is no function by that name to call")) - next() + + if(is.function(rule$name)) { + ruleFun <- rule$name + } else { + if(exists(rule$name, mode="function")) { + ruleFun <- get(rule$name, mode="function") + } else { + rule.name <- paste("rule", rule$name, sep=".") + if(exists(rule.name, mode="function")) { + ruleFun <- get(rule.name, mode="function") + rule$name <- rule.name } else { - rule$name<-paste("rule",rule$name,sep='.') + message("Skipping rule ", rule$name, + " because there is no function by that name to call") + next } - } + } } - + if(!isTRUE(rule$enabled)) next() # check to see if we should run in this timespan @@ -696,7 +708,7 @@ if(!is.null(rule$arguments$prefer)) .formals$prefer = rule$arguments$prefer # evaluate rule in applyRules' environment - tmp_val <- do.call(rule$name, .formals, envir=parent.frame(1)) + tmp_val <- do.call(ruleFun, .formals, envir=parent.frame(1)) # print(paste('tmp_val ==', tmp_val)) } #end rules loop Modified: pkg/quantstrat/R/signals.R =================================================================== --- pkg/quantstrat/R/signals.R 2016-04-03 14:22:28 UTC (rev 1744) +++ pkg/quantstrat/R/signals.R 2016-04-03 14:50:14 UTC (rev 1745) @@ -93,16 +93,25 @@ for (signal in strategy$signals){ #TODO check to see if they've already been calculated - - if(!is.function(get(signal$name))){ - if(!is.function(get(paste("sig",signal$name,sep='.')))){ - message(paste("Skipping signal",signal$name,"because there is no function by that name to call")) - next() + + if(is.function(signal$name)) { + sigFun <- signal$name + } else { + if(exists(signal$name, mode="function")) { + sigFun <- get(signal$name, mode="function") } else { - signal$name<-paste("sig",signal$name,sep='.') + sig.name <- paste("sig", signal$name, sep=".") + if(exists(sig.name, mode="function")) { + sigFun <- get(sig.name, mode="function") + signal$name <- sig.name + } else { + message("Skipping signal ", signal$name, + " because there is no function by that name to call") + next + } } } - + if(!isTRUE(signal$enabled)) next() # replace default function arguments with signal$arguments @@ -115,7 +124,7 @@ # remove ... to avoid matching multiple args .formals$`...` <- NULL - tmp_val <- do.call(signal$name, .formals) + tmp_val <- do.call(sigFun, .formals) #add label if(is.null(colnames(tmp_val))) Modified: pkg/quantstrat/R/wrapup.R =================================================================== --- pkg/quantstrat/R/wrapup.R 2016-04-03 14:22:28 UTC (rev 1744) +++ pkg/quantstrat/R/wrapup.R 2016-04-03 14:50:14 UTC (rev 1745) @@ -102,9 +102,16 @@ #first do whatever the user stuck in this wrapup slot... if(length(strategy$wrapup)>0){ for (wrapup_o in strategy$wrapup){ - if(!is.function(get(wrapup_o$name))){ - message(paste("Skipping wrapup",wrapup_o$name,"because there is no function by that name to call")) - next() + if(is.function(wrapup_o$name)) { + wrapup_oFun <- wrapup_o$name + } else { + if(exists(wrapup_o$name, mode="function")) { + wrapup_oFun <- get(wrapup_o$name, mode="function") + } else { + message("Skipping wrapup function ", wrapup_o$name, + " because there is no function by that name to call.") + next + } } if(!isTRUE(wrapup_o$enabled)) next() @@ -119,7 +126,7 @@ # remove ... to avoid matching multiple args .formals$`...` <- NULL - out[[wrapup_o$name]] <- do.call(wrapup_o$name, .formals) + out[[wrapup_o$name]] <- do.call(wrapup_oFun, .formals) } } From noreply at r-forge.r-project.org Thu Apr 7 01:48:19 2016 From: noreply at r-forge.r-project.org (noreply at r-forge.r-project.org) Date: Thu, 7 Apr 2016 01:48:19 +0200 (CEST) Subject: [Blotter-commits] r1746 - in pkg/quantstrat: R man Message-ID: <20160406234819.81322187AFD@r-forge.r-project.org> Author: bodanker Date: 2016-04-07 01:48:18 +0200 (Thu, 07 Apr 2016) New Revision: 1746 Modified: pkg/quantstrat/R/orders.R pkg/quantstrat/man/getOrders.Rd Log: Make explicit that getOrders works with one symbol getOrders will throw an error if 'symbol' is a vector and not in the same order as the symbols in the portfolio. If that error is avoided because the symbols are in the same order, then there will be an error when we try to subset orderbook[[portfolio]] by a vector, since [[ can only select a single element. Modified: pkg/quantstrat/R/orders.R =================================================================== --- pkg/quantstrat/R/orders.R 2016-04-03 14:50:14 UTC (rev 1745) +++ pkg/quantstrat/R/orders.R 2016-04-06 23:48:18 UTC (rev 1746) @@ -96,8 +96,6 @@ #' #' It has some use as a reporting or post-hoc analytics tool, but it may not always be exported. #' -#' should this be symbols instead of symbol? -#' #' @param portfolio text name of the portfolio to associate the order book with #' @param symbol identifier 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", "revoked", or "replaced", default "open" @@ -116,7 +114,14 @@ #if(is.null(timespan)) stop("timespan must be an xts style timestring") # get order book orderbook <- getOrderBook(portfolio) - if(!any(names(orderbook[[portfolio]]) == symbol)) stop(paste("symbol",symbol,"does not exist in portfolio",portfolio,"having symbols",names(orderbook[[portfolio]]))) + if(length(symbol) > 1L) { + symbol <- symbol[1L] # only one symbol at a time is currently supported + warning("Only single instruments are currently supported. Using first symbol only.") + } + if(!any(names(orderbook[[portfolio]]) == symbol)) { + stop("symbol ", symbol, " does not exist in portfolio ", portfolio, + ", which has symbols: ", paste(names(orderbook[[portfolio]]), collapse=", ")) + } ordersubset <- orderbook[[portfolio]][[symbol]] if(is.null(ordersubset)) Modified: pkg/quantstrat/man/getOrders.Rd =================================================================== --- pkg/quantstrat/man/getOrders.Rd 2016-04-03 14:50:14 UTC (rev 1745) +++ pkg/quantstrat/man/getOrders.Rd 2016-04-06 23:48:18 UTC (rev 1746) @@ -32,8 +32,6 @@ } \details{ It has some use as a reporting or post-hoc analytics tool, but it may not always be exported. - -should this be symbols instead of symbol? } \seealso{ getOrderBook From noreply at r-forge.r-project.org Sat Apr 9 15:18:05 2016 From: noreply at r-forge.r-project.org (noreply at r-forge.r-project.org) Date: Sat, 9 Apr 2016 15:18:05 +0200 (CEST) Subject: [Blotter-commits] r1747 - in pkg/quantstrat/sandbox: . paramtest201604 Message-ID: <20160409131805.C03B0187E77@r-forge.r-project.org> Author: braverock Date: 2016-04-09 15:18:05 +0200 (Sat, 09 Apr 2016) New Revision: 1747 Added: pkg/quantstrat/sandbox/paramtest201604/ pkg/quantstrat/sandbox/paramtest201604/processingtime_q.R pkg/quantstrat/sandbox/paramtest201604/processingtime_q.paramset.R pkg/quantstrat/sandbox/paramtest201604/processingtime_q.ps.R pkg/quantstrat/sandbox/paramtest201604/processingtime_q_rsigfinance.csv Log: - add paramset test prompted by R-SIG-Finance thread "Processing time of backtests on a single computer" Added: pkg/quantstrat/sandbox/paramtest201604/processingtime_q.R =================================================================== --- pkg/quantstrat/sandbox/paramtest201604/processingtime_q.R (rev 0) +++ pkg/quantstrat/sandbox/paramtest201604/processingtime_q.R 2016-04-09 13:18:05 UTC (rev 1747) @@ -0,0 +1,219 @@ +#library(lattice) +library(foreach) +#library(doSNOW) +#library(ggplot2) +library(PerformanceAnalytics) +#require(latticeExtra) +#require(grid) +#library(gridExtra) +#library(reshape) +library(quantstrat) + +.strategy<- new.env() +.blotter<- new.env() + +currency(c('USD', 'EUR')) +exchange_rate(primary_id="EURUSD", tick_size=0.0001) + +data.location.r <- "processingtime_q_rsigfinance.csv" +symbol.data <- as.xts(read.zoo(data.location.r, sep=',', tz="",header=TRUE, format='%d/%m/%Y %H:%M', index.column = 1)) +symbol.data <- symbol.data[symbol.data$VOLUME!=0,] +symbol.data[,c(1,2,3,4)] <- round(as.numeric(symbol.data[,c(1,2,3,4)]),abs(log10(0.0001))) +assign("EURUSD", symbol.data) + +strategy.st <- "rsigfinance" +rm.strat(strategy.st) + +initDate = as.character(as.Date(index(symbol.data[1])-1)) +initPortf(strategy.st, "EURUSD", initDate=initDate, currency = "USD") +initAcct(strategy.st, portfolios=strategy.st, initDate=initDate, initEq=100000, currency = "USD") +initOrders(portfolio=strategy.st,initDate=initDate) +strategy(strategy.st,store=TRUE) +summary(getStrategy(strategy.st)) + +positionSizeLong = round(100000 / as.numeric(symbol.data$CLOSE[1]),-2) +positionSizeShort = - round(100000 / as.numeric(symbol.data$CLOSE[1]),-2) +txn.model <- 0 +sltsltp.txn.fee <- 0 + +add.indicator(strategy.st, + name = "MACD", + arguments = list(x=Cl(eval(parse(text = "EURUSD")))), + label='macd') + +add.signal(strategy.st,name="sigCrossover", + arguments = list(columns=c("macd.macd","signal.macd"),relationship="gt"), + label="macd.gt.signal") + +add.signal(strategy.st,name="sigCrossover", + arguments = list(columns=c("macd.macd","signal.macd"),relationship="lt"), + label="macd.lt.signal") + +add.rule(strategy.st, + name='ruleSignal', + arguments = list(sigcol="macd.gt.signal", + sigval=TRUE, + prefer="Open", + orderqty= positionSizeLong, + ordertype='market', + orderside='long', + orderset='ocolong', + TxnFees = txn.model), + type='enter', + label='longenter', + enabled=TRUE +) + +add.rule(strategy.st, + name='ruleSignal', + arguments = list(sigcol="macd.lt.signal", + sigval=TRUE, + prefer="Open", + orderqty='all', + ordertype='market', + orderside='long', + orderset='ocolong', + TxnFees = txn.model), + type='exit', + label='longexit', + enabled=TRUE +) + +add.rule(strategy.st,name='ruleSignal', + arguments = list( sigcol="macd.lt.signal", sigval=TRUE, + replace=FALSE, + orderside='long', + ordertype='stoplimit', + tmult=TRUE, + threshold=quote( longStopLossDistance ), + orderqty='all', + orderset='ocolong', + TxnFees = txn.model), + type='chain', parent="longenter", + label='StopLossLong', + enabled=TRUE) + +add.rule(strategy.st, name = 'ruleSignal', + arguments=list(sigcol="macd.lt.signal" , sigval=TRUE, + replace=FALSE, + orderside='long', + ordertype='stoptrailing', + tmult=TRUE, + threshold=quote(longTrailingStopDistance), + orderqty='all', + orderset='ocolong', + TxnFees = txn.model), + type='chain', parent="longenter", + label='StopTrailingLong', + enabled=FALSE +) + +add.rule(strategy.st, name = "ruleSignal", + arguments = list(sigcol="macd.lt.signal", + sigval=TRUE, + ordertype="limit", + orderside="long", + replace=FALSE, + tmult=TRUE, + threshold=quote(longTakeProfitDistance), + orderqty="all", + orderset="ocolong", + TxnFees = txn.model), + type = "chain", parent="longenter", + label = "takeProfitLong", + enabled = FALSE +) + +add.rule(strategy.st, + name='ruleSignal', + arguments = list(sigcol="macd.lt.signal", + sigval=TRUE, + prefer="Open", + orderqty=positionSizeShort, + ordertype='market', + orderside='short', + orderset='ocoshort', + TxnFees = txn.model), + type='enter', + label='shortenter', + enabled=TRUE +) + +add.rule(strategy.st, + name='ruleSignal', + arguments = list(sigcol="macd.gt.signal", + sigval=TRUE, + prefer="Open", + orderqty='all', + ordertype='market', + orderside='short', + orderset='ocoshort', + TxnFees = txn.model), + type='exit', + label='shortexit', + enabled=TRUE +) + +add.rule(strategy.st,name='ruleSignal', + arguments = list( sigcol="macd.gt.signal", sigval=TRUE, + replace=FALSE, + orderside='short', + ordertype='stoplimit', + tmult=TRUE, + threshold=quote( shortStopLossDistance ), + orderqty='all', + orderset='ocoshort', + TxnFees = txn.model), + type='chain', parent="shortenter", + label='StopLossShort', + enabled=TRUE) + +add.rule(strategy.st, name = 'ruleSignal', + arguments=list(sigcol="macd.gt.signal" , sigval=TRUE, + replace=FALSE, + orderside='short', + ordertype='stoptrailing', + tmult=TRUE, + threshold=quote( shortTrailingStopDistance), + orderqty='all', + orderset='ocoshort', + TxnFees = txn.model), + type='chain', parent="shortenter", + label='StopTrailingShort', + enabled=FALSE +) + +add.rule(strategy.st, name = "ruleSignal", + arguments = list(sigcol="macd.gt.signal", + sigval=TRUE, + ordertype="limit", + orderside="short", + replace=FALSE, + tmult=TRUE, + threshold=quote( -shortTakeProfitDistance), + orderqty="all", + orderset="ocoshort", + TxnFees = txn.model), + type = "chain", parent="shortenter", + label = "takeProfitShort", + enabled = FALSE +) + + +summary(getStrategy(strategy.st)) + + +start.t <- Sys.time() +nFast <- 9 +nSlow <- 24 +nSignal <- 7 +longStopLossDistance <- 0.01;longTrailingStopDistance <- 0.01;longTakeProfitDistance <- 0.01 +shortStopLossDistance <- 0.01;shortTrailingStopDistance <- 0.01;shortTakeProfitDistance <- 0.01 + +results <- applyStrategy( strategy=strategy.st , portfolios=strategy.st, + parameters=list(nFast=nFast, nSlow=nSlow, nSig=nSignal),verbose=TRUE) +updatePortf(strategy.st) +updateAcct(strategy.st) +updateEndEq(strategy.st) +finish.t <- Sys.time() +print(finish.t-start.t) \ No newline at end of file Added: pkg/quantstrat/sandbox/paramtest201604/processingtime_q.paramset.R =================================================================== --- pkg/quantstrat/sandbox/paramtest201604/processingtime_q.paramset.R (rev 0) +++ pkg/quantstrat/sandbox/paramtest201604/processingtime_q.paramset.R 2016-04-09 13:18:05 UTC (rev 1747) @@ -0,0 +1,297 @@ +#library(lattice) +library(foreach) +library(doSNOW) +#library(ggplot2) +library(PerformanceAnalytics) +#library(doSNOW) +#require(latticeExtra) +#require(grid) +#library(gridExtra) +#library(reshape) +library(quantstrat) + +no.cores <- 12 + +.strategy<- new.env() +.blotter<- new.env() + +currency(c('USD', 'EUR')) +exchange_rate(primary_id="EURUSD", tick_size=0.0001) + +data.location.r <- "processingtime_q_rsigfinance.csv" +symbol.data <- as.xts(read.zoo(data.location.r, sep=',', tz="",header=TRUE, format='%d/%m/%Y %H:%M', index.column = 1)) +symbol.data <- symbol.data[symbol.data$VOLUME!=0,] # Delete rows with no volume (when the market is closed) +symbol.data[,c(1,2,3,4)] <- round(as.numeric(symbol.data[,c(1,2,3,4)]),abs(log10(0.0001))) #datay? tick sizela uyumlu yapma +assign("EURUSD", symbol.data) + +strategy.st <- "rsigfinance" +rm.strat(strategy.st) + +initDate = as.character(as.Date(index(symbol.data[1])-1)) +initPortf(strategy.st, "EURUSD", initDate=initDate, currency = "USD") +initAcct(strategy.st, portfolios=strategy.st, initDate=initDate, initEq=100000, currency = "USD") +initOrders(portfolio=strategy.st,initDate=initDate) +strategy(strategy.st,store=TRUE) +summary(getStrategy(strategy.st)) + +macdFastMARange <- seq(2,17,by=5) +macdSlowMARange <- seq(5,35,by=10) +macdSignalRange <- seq(2,18,by=8) + +StopLossDistanceRange <- seq(0.01,0.02,by=0.01) +TrailingDistanceRange <- seq(0.01,0.02,by=0.01) + +positionSizeLong = round(100000 / as.numeric(symbol.data$CLOSE[1]),-2) +positionSizeShort = - round(100000 / as.numeric(symbol.data$CLOSE[1]),-2) +txn.model <- 0 +sltsltp.txn.fee <- 0 + + +add.indicator(strategy.st, + name = "MACD", + arguments = list(x=Cl(eval(parse(text = "EURUSD")))), + label='macd') + +add.signal(strategy.st,name="sigCrossover", + arguments = list(columns=c("macd.macd","signal.macd"),relationship="gt"), + label="macd.gt.signal") + +add.signal(strategy.st,name="sigCrossover", + arguments = list(columns=c("macd.macd","signal.macd"),relationship="lt"), + label="macd.lt.signal") + +add.rule(strategy.st, + name='ruleSignal', + arguments = list(sigcol="macd.gt.signal", + sigval=TRUE, + prefer="Open", + orderqty= positionSizeLong, + ordertype='market', + orderside='long', + orderset='ocolong', + TxnFees = txn.model), + type='enter', + label='longenter', + enabled=TRUE +) + +add.rule(strategy.st, + name='ruleSignal', + arguments = list(sigcol="macd.lt.signal", + sigval=TRUE, + prefer="Open", + orderqty='all', + ordertype='market', + orderside='long', + orderset='ocolong', + TxnFees = txn.model), + type='exit', + label='longexit', + enabled=TRUE +) + +add.rule(strategy.st,name='ruleSignal', + arguments = list( sigcol="macd.lt.signal", sigval=TRUE, + replace=FALSE, + orderside='long', + ordertype='stoplimit', + tmult=TRUE, + threshold=quote( longStopLossDistance ), + orderqty='all', + orderset='ocolong', + TxnFees = txn.model), + type='chain', parent="longenter", + label='StopLossLong', + enabled=TRUE) + +add.rule(strategy.st, name = 'ruleSignal', + arguments=list(sigcol="macd.lt.signal" , sigval=TRUE, + replace=FALSE, + orderside='long', + ordertype='stoptrailing', + tmult=TRUE, + threshold=quote(longTrailingStopDistance), + orderqty='all', + orderset='ocolong', + TxnFees = txn.model), + type='chain', parent="longenter", + label='StopTrailingLong', + enabled=TRUE +) + +# add.rule(strategy.st, name = "ruleSignal", +# arguments = list(sigcol="macd.lt.signal", +# sigval=TRUE, +# ordertype="limit", +# orderside="long", +# replace=FALSE, +# tmult=TRUE, +# threshold=quote(longTakeProfitDistance), +# orderqty="all", +# orderset="ocolong", +# TxnFees = txn.model), +# type = "chain", parent="longenter", +# label = "takeProfitLong", +# enabled = FALSE +# ) + +add.rule(strategy.st, + name='ruleSignal', + arguments = list(sigcol="macd.lt.signal", + sigval=TRUE, + prefer="Open", + orderqty=positionSizeShort, + ordertype='market', + orderside='short', + orderset='ocoshort', + TxnFees = txn.model), + type='enter', + label='shortenter', + enabled=TRUE +) + +add.rule(strategy.st, + name='ruleSignal', + arguments = list(sigcol="macd.gt.signal", + sigval=TRUE, + prefer="Open", + orderqty='all', + ordertype='market', + orderside='short', + orderset='ocoshort', + TxnFees = txn.model), + type='exit', + label='shortexit', + enabled=TRUE +) + +add.rule(strategy.st,name='ruleSignal', + arguments = list( sigcol="macd.gt.signal", sigval=TRUE, + replace=FALSE, + orderside='short', + ordertype='stoplimit', + tmult=TRUE, + threshold=quote( shortStopLossDistance ), + orderqty='all', + orderset='ocoshort', + TxnFees = txn.model), + type='chain', parent="shortenter", + label='StopLossShort', + enabled=TRUE) + +add.rule(strategy.st, name = 'ruleSignal', + arguments=list(sigcol="macd.gt.signal" , sigval=TRUE, + replace=FALSE, + orderside='short', + ordertype='stoptrailing', + tmult=TRUE, + threshold=quote( shortTrailingStopDistance), + orderqty='all', + orderset='ocoshort', + TxnFees = txn.model), + type='chain', parent="shortenter", + label='StopTrailingShort', + enabled=TRUE +) + +# add.rule(strategy.st, name = "ruleSignal", +# arguments = list(sigcol="macd.gt.signal", +# sigval=TRUE, +# ordertype="limit", +# orderside="short", +# replace=FALSE, +# tmult=TRUE, +# threshold=quote( -shortTakeProfitDistance), +# orderqty="all", +# orderset="ocoshort", +# TxnFees = txn.model), +# type = "chain", parent="shortenter", +# label = "takeProfitShort", +# enabled = FALSE +# ) + + +add.distribution(strategy.st, + paramset.label = "MACD_OPT", + component.type = 'indicator', + component.label = "macd", + variable = list( nFast = macdFastMARange ), + label = "macdFastMARANGE") + + +add.distribution(strategy.st, + paramset.label = "MACD_OPT", + component.type = 'indicator', + component.label = "macd", + variable = list( nSlow = macdSlowMARange ), + label = "macdSlowMARANGE") + +add.distribution(strategy.st, + paramset.label = "MACD_OPT", + component.type = 'indicator', + component.label = "macd", + variable = list( nSig = macdSignalRange ), + label = "macdSignalRANGE") + +add.distribution.constraint(strategy.st, + paramset.label = 'MACD_OPT', + distribution.label.1 = 'macdFastMARANGE', + distribution.label.2 = 'macdSlowMARANGE', + operator = '<', + label = 'FastMA Author: braverock Date: 2016-04-17 20:25:28 +0200 (Sun, 17 Apr 2016) New Revision: 1748 Modified: pkg/quantstrat/sandbox/backtest_musings/stat_process.bib pkg/quantstrat/sandbox/backtest_musings/strat_dev_process.Rmd pkg/quantstrat/sandbox/backtest_musings/strat_dev_process.pdf Log: - update public version of strategy development process essay Modified: pkg/quantstrat/sandbox/backtest_musings/stat_process.bib =================================================================== --- pkg/quantstrat/sandbox/backtest_musings/stat_process.bib 2016-04-09 13:18:05 UTC (rev 1747) +++ pkg/quantstrat/sandbox/backtest_musings/stat_process.bib 2016-04-17 18:25:28 UTC (rev 1748) @@ -1,4 +1,3 @@ -% This file was created with JabRef 2.10. % Encoding: UTF-8 @@ -12,6 +11,24 @@ Author_sort = {Aronson, David} } + at Article{Bailey2014deSharpe, + Title = {The Deflated Sharpe Ratio: Correcting for Selection Bias, Backtest Overfitting and Non-Normality}, + Author = {Bailey, David H and {L{\'o}pez de Prado}, Marcos}, + Journal = {Journal of Portfolio Management, Forthcoming}, + Year = {2014}, + + Url = {http://www.davidhbailey.com/dhbpapers/deflated-sharpe.pdf} +} + + at Article{Bailey2014drawdown, + Title = {Drawdown-Based Stop-Outs and the 'Triple Penance' Rule}, + Author = {Bailey, David H and {L{\'o}pez de Prado}, Marcos}, + Journal = {Journal of Risk}, + Year = {forthcoming, 2014}, + + Url = {http://papers.ssrn.com/sol3/papers.cfm?abstract_id=2201302} +} + @Article{Bailey2014pm, Title = {Pseudomathematics and financial charlatanism: The effects of backtest {O}ver fitting on out-of-sample performance}, Author = {Bailey, David H and Borwein, Jonathan M and {L{\'o}pez de Prado}, Marcos and Zhu, Qiji Jim}, @@ -30,24 +47,6 @@ Url = {http://papers.ssrn.com/sol3/papers.cfm?abstract_id=2326253} } - at Article{Bailey2014drawdown, - Title = {Drawdown-Based Stop-Outs and the 'Triple Penance' Rule}, - Author = {Bailey, David H and {L{\'o}pez de Prado}, Marcos}, - Journal = {Journal of Risk}, - Year = {forthcoming, 2014}, - - Url = {http://papers.ssrn.com/sol3/papers.cfm?abstract_id=2201302} -} - - at Article{Bailey2014deSharpe, - Title = {The Deflated Sharpe Ratio: Correcting for Selection Bias, Backtest Overfitting and Non-Normality}, - Author = {Bailey, David H and {L{\'o}pez de Prado}, Marcos}, - Journal = {Journal of Portfolio Management, Forthcoming}, - Year = {2014}, - - Url = {http://www.davidhbailey.com/dhbpapers/deflated-sharpe.pdf} -} - @Article{baquero2005, Title = {Survival, look-ahead bias, and persistence in hedge fund performance}, Author = {Baquero, Guillermo and Ter Horst, Jenke and Verbeek, Marno}, @@ -109,13 +108,21 @@ Pages = {2079--2107}, Volume = {11}, - __markedentry = {[brian:]}, Owner = {brian}, Publisher = {JMLR. org}, Timestamp = {2015.06.10}, Url = {http://www.jmlr.org/papers/volume11/cawley10a/cawley10a.pdf} } + at Article{Chang2015, + author = {Chang, Andrew C and Li, Phillip}, + title = {Is Economics Research Replicable? Sixty Published Papers from Thirteen Journals Say'Usually Not'}, + year = {2015}, + __markedentry = {[brian:6]}, + publisher = {FEDS Working Paper}, + url = {https://www.federalreserve.gov/econresdata/feds/2015/files/2015083pap.pdf} +} + @Article{Diedesch2014, Title = {2014 Forty Under Forty}, Author = {Diedesch, Josh}, @@ -126,6 +133,18 @@ Url = {http://www.ai-cio.com/Forty_Under_Forty_2014.aspx?page=9} } + at Article{Economist2013, + Title = {Unreliable Research: Trouble at the lab}, + Journal = {Economist}, + Year = {2013}, + + Month = {Oct 19}, + + Owner = {brian}, + Timestamp = {2015.01.14}, + Url = {http://www.economist.com/news/briefing/21588057-scientists-think-science-self-correcting-alarming-degree-it-not-trouble} +} + @Book{Feynman1965, Title = {The Feynman Lectures on Physics}, Author = {Feynman, Richard P and Leighton, Robert B and Sands, Matthew and Hafner, EM}, @@ -139,7 +158,7 @@ Publisher = {John Wiley \& Sons, Inc.}, Year = {2013}, - Subtitle = {Tradable Strategies That Perform as They Backtest and Meet Your Risk-Reward Goals} + Ssubtitle = {Tradable Strategies That Perform as They Backtest and Meet Your Risk-Reward Goals} } @Misc{Fox2011, @@ -153,11 +172,14 @@ Timestamp = {2015.01.13} } - at Manual{parma2014, - Title = {parma: portfolio allocation and risk management applications.}, - Author = {Alexios Ghalanos and Bernhard Pfaff}, - Note = {R package version 1.5-1.}, - Year = {2014} + at Book{goldman1998practice, + Title = {The practice of risk management}, + Author = {Litterman, Robert and Gumerlock, Robert }, + Publisher = {Euromoney}, + Year = {1998}, + + Authorsort = {Litterman, Robert and Gumerlock, Robert}, + Ssubtitle = {Implementing processes for managing firmwide market risk} } @Article{Hansen2005, @@ -167,19 +189,6 @@ Year = {2005} } - at Article{Harvey2014, - Title = {Evaluating Trading Strategies}, - Author = {Harvey, Campbell R. and Liu, Yan}, - Journal = {Journal of Portfolio Management}, - Year = {2014}, - Number = {5}, - Pages = {108-118}, - Volume = {40}, - - Comment = {preprint at http://ssrn.com/abstract=2474755}, - Url = {https://faculty.fuqua.duke.edu/~charvey/Research/Published_Papers/P116_Evaluating_trading_strategies.pdf} -} - @Article{Harvey2013backtesting, Title = {Backtesting}, Author = {Harvey, Campbell R. and Liu, Yan}, @@ -198,6 +207,19 @@ Url = {http://ssrn.com/abstract=2358214} } + at Article{Harvey2014, + Title = {Evaluating Trading Strategies}, + Author = {Harvey, Campbell R. and Liu, Yan}, + Journal = {Journal of Portfolio Management}, + Year = {2014}, + Number = {5}, + Pages = {108-118}, + Volume = {40}, + + Comment = {preprint at http://ssrn.com/abstract=2474755}, + Url = {https://faculty.fuqua.duke.edu/~charvey/Research/Published_Papers/P116_Evaluating_trading_strategies.pdf} +} + @Book{Hastie2009, Title = {The elements of statistical learning: Data mining, inference, and prediction. Second Edition}, Author = {Hastie, Trevor and Tibshirani, Robert and Friedman, Jerome}, @@ -244,12 +266,23 @@ Number = {8}, Pages = {e124}, Volume = {2}, + Owner = {brian}, Publisher = {Public Library of Science}, Timestamp = {2015.01.29}, Url = {http://journals.plos.org/plosmedicine/article?id=10.1371/journal.pmed.0020124#s6} } + at Book{Jones1999, + Title = {The trading game}, + Author = {Jones, Ryan}, + Publisher = {John Wiley \& Sons}, + Year = {1999}, + Owner = {brian}, + Ssubtitle = {playing by the numbers to make millions}, + Timestamp = {2015.08.13} +} + @Article{Kaastra1996, Title = {Designing a neural network for forecasting financial and economic time series}, Author = {Kaastra, Iebeling and Boyd, Milton}, @@ -264,6 +297,17 @@ Timestamp = {2015.05.19} } + at Book{Kaufman2013, + Title = {Trading systems and methods}, + Author = {Kaufman, Perry J}, + Publisher = {John Wiley \& Sons}, + Year = {2013}, + Edition = {Fifth ed.}, + + Owner = {brian}, + Timestamp = {2015.08.12} +} + @Article{Keogh2003, Title = {On the need for time series data mining benchmarks: a survey and empirical demonstration}, Author = {Keogh, Eamonn and Kasetty, Shruti}, @@ -273,13 +317,28 @@ Pages = {349--371}, Volume = {7}, - __markedentry = {[brian:6]}, Owner = {brian}, Publisher = {Springer}, Timestamp = {2015.06.10}, Url = {http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.13.2240&rep=rep1&type=pdf} } + at Article{Kerr1998, + author = {Kerr, Norbert L}, + title = {HARKing: Hypothesizing after the results are known}, + journal = {Personality and Social Psychology Review}, + year = {1998}, + volume = {2}, + number = {3}, + pages = {196--217}, + __markedentry = {[brian:]}, + file = {:/home/brian/docs/Research/HARKing_ Hypothesizing_After_the_Results_are_Known_1998_Kerr.pdf:PDF}, + owner = {brian}, + publisher = {Sage Publications}, + timestamp = {2016.02.25}, + url = {http://psr.sagepub.com/content/2/3/196.abstract} +} + @Book{Kestner2003, Title = {Quantitative trading strategies: {H}arnessing the power of quantitative techniques to create a winning trading program}, Author = {Kestner, Lars}, @@ -313,19 +372,6 @@ Url = {http://appliedpredictivemodeling.com/} } - at InProceedings{Sweave2002, - Title = {Sweave: Dynamic Generation of Statistical Reports Using Literate Data Analysis}, - Author = {Friedrich Leisch}, - Booktitle = {Compstat 2002 --- Proceedings in Computational Statistics}, - Year = {2002}, - Editor = {Wolfgang H{\"a}rdle and Bernd R{\"o}nz}, - Note = {ISBN 3-7908-1517-9}, - Pages = {575--580}, - Publisher = {Physica Verlag, Heidelberg}, - - Url = {http://www.stat.uni-muenchen.de/~leisch/Sweave} -} - @Article{Levy2006, Title = {A systems approach to conduct an effective literature review in support of information systems research}, Author = {Levy, Yair and Ellis, Timothy J}, @@ -341,6 +387,29 @@ Url = {http://inform.nu/Articles/Vol9/V9p181-212Levy99.pdf} } + at Article{Markowitz1994, + author = {Markowitz, Harry M and Xu, Gan Lin}, + title = {Data mining corrections}, + journal = {The Journal of Portfolio Management}, + year = {1994}, + volume = {21}, + number = {1}, + pages = {60--69}, + owner = {brian}, + publisher = {Institutional Investor Journals}, + timestamp = {2015.08.19} +} + + at Misc{mistakes2011, + Title = {Common ~~ misteaks ~~ mistakes in using statistics: Spotting and Avoiding Them - Data Snooping}, + + Author = {Martha K. Smith}, + + Accessed = {2014-09-23}, + Author_sort = {Smith, Martha}, + Url = {https://www.ma.utexas.edu/users/mks/statmistakes/datasnooping.html} +} + @Article{Moonesinghe2007, Title = {Most published research findings are false, but a little replication goes a long way}, Author = {Moonesinghe, Ramal and Khoury, Muin J and Janssens, A Cecile JW}, @@ -356,16 +425,34 @@ Url = {http://journals.plos.org/plosmedicine/article?id=info:doi/10.1371/journal.pmed.0040028} } + at Book{Narang2013, + Title = {Inside the Black Box: A Simple Guide to Quantitative and High Frequency Trading}, + Author = {Narang, Rishi K}, + Publisher = {John Wiley \& Sons}, + Year = {2013}, + + Owner = {brian}, + Timestamp = {2015.06.18} +} + @Book{Pardo2008, - Title = {The evaluation and optimization of trading strategies, second edition}, + Title = {The evaluation and optimization of trading strategies}, Author = {Robert Pardo}, Publisher = {John Wiley \& Sons}, Year = {2008}, + Edition = {Second ed.}, Month = {Feb}, Author_sort = {Pardo, Robert} } + at Manual{parma2014, + Title = {parma: portfolio allocation and risk management applications.}, + Author = {Alexios Ghalanos and Bernhard Pfaff}, + Note = {R package version 1.5-1.}, + Year = {2014} +} + @Article{Peng2011, Title = {Reproducible research in computational science}, Author = {Peng, Roger D}, @@ -381,6 +468,15 @@ Url = {http://www.ncbi.nlm.nih.gov/pmc/articles/PMC3383002/} } + at Manual{perfa2014, + Title = {PerformanceAnalytics: Econometric tools for performance and risk analysis}, + Author = {Brian G. Peterson and Peter Carl}, + Year = {2015}, + + Subtitle = {R package version 1.4.3541}, + Url = {http://CRAN.R-project.org/package=PerformanceAnalytics} +} + @TechReport{Peterson2015, Title = {Developing \& Backtesting Systematic Trading Strategies}, Author = {Peterson, Brian G}, @@ -390,15 +486,6 @@ Url = {http://goo.gl/na4u5d} } - at Manual{perfa2014, - Title = {PerformanceAnalytics: Econometric tools for performance and risk analysis}, - Author = {Brian G. Peterson and Peter Carl}, - Year = {2015}, - - Subtitle = {R package version 1.4.3541}, - Url = {http://CRAN.R-project.org/package=PerformanceAnalytics} -} - @Manual{porta2014, Title = {PortfolioAnalytics: Portfolio Analysis, including Numerical Methods for Optimization of Portfolios}, Author = {Brian G. Peterson and Peter Carl and Ross Bennett and Kris Boudt}, @@ -445,14 +532,15 @@ Pages = {155--170} } - at Misc{mistakes2011, - Title = {Common ~~ misteaks ~~ mistakes in using statistics: Spotting and Avoiding Them - Data Snooping}, + at Misc{Rmarkdown, + Title = {R Markdown ? Dynamic Documents for R}, - Author = {Martha K. Smith}, + Author = {Yihui Xie}, + Year = {2014}, - Accessed = {2014-09-23}, - Author_sort = {Smith, Martha}, - Url = {https://www.ma.utexas.edu/users/mks/statmistakes/datasnooping.html} + Owner = {brian}, + Timestamp = {2015.01.13}, + Url = {http://rmarkdown.rstudio.com/} } @Article{Sullivan1999, @@ -465,16 +553,27 @@ Volume = {54} } - at Misc{Tomasini2009, + at InProceedings{Sweave2002, + Title = {Sweave: Dynamic Generation of Statistical Reports Using Literate Data Analysis}, + Author = {Friedrich Leisch}, + Booktitle = {Compstat 2002 --- Proceedings in Computational Statistics}, + Year = {2002}, + Editor = {Wolfgang H{\"a}rdle and Bernd R{\"o}nz}, + Note = {ISBN 3-7908-1517-9}, + Pages = {575--580}, + Publisher = {Physica Verlag, Heidelberg}, + + Url = {http://www.stat.uni-muenchen.de/~leisch/Sweave} +} + + at Book{Tomasini2009, Title = {Trading Systems: A New Approach to System Development and Portfolio Optimisation }, - Author = {Emilio Tomasini and Urban Jaekle}, + Year = {2009}, Month = {Dec}, - Year = {2009}, Author_sort = {Tomasini, Emilio \& Jaekle, Urban}, - Title_sort = {Trading Systems A New Approach to System Development and Portfolio Optimisation}, - Volume = {1} + Title_sort = {Trading Systems A New Approach to System Development and Portfolio Optimisation} } @Article{Tukey1962, @@ -488,12 +587,22 @@ Url = {http://projecteuclid.org/euclid.aoms/1177704711} } + at Book{Vince1992, + Title = {The mathematics of money management}, + Author = {Vince, Ralph}, + Publisher = {John Wiley \& Sons}, + Year = {1992}, + + Owner = {brian}, + Ssubtitle = {Risk Analysis Techniques for traders}, + Timestamp = {2015.08.12} +} + @Book{Vince2009, Title = {The leverage space trading model}, Author = {Vince, Ralph}, - Publisher = {John Wiley and Sons}, + Publisher = {John Wiley \& Sons}, Year = {2009}, - Volume = {425}, Subtitle = {Reconciling portfolio management strategies and economic theory} } @@ -509,6 +618,17 @@ Url = {http://openeconomics.net/resources/data-policies-of-economic-journals/} } + at Book{Weissman2005, + Title = {Mechanical trading systems}, + Author = {Weissman, Richard L}, + Publisher = {John Wiley \& Sons}, + Year = {2005}, + + Owner = {brian}, + Ssubtitle = {Pairing trader psychology with technical analysis}, + Timestamp = {2015.08.12} +} + @Misc{White2000, Title = {System and method for testing prediction models and/or entities}, @@ -522,26 +642,3 @@ Url = {http://www.google.com/patents/US6088676} } - at Misc{Rmarkdown, - Title = {R Markdown ? Dynamic Documents for R}, - - Author = {Yihui Xie}, - Year = {2014}, - - Owner = {brian}, - Timestamp = {2015.01.13}, - Url = {http://rmarkdown.rstudio.com/} -} - - at Article{Economist2013, - Title = {Unreliable Research: Trouble at the lab}, - Journal = {Economist}, - Year = {2013}, - - Month = {Oct 19}, - - Owner = {brian}, - Timestamp = {2015.01.14}, - Url = {http://www.economist.com/news/briefing/21588057-scientists-think-science-self-correcting-alarming-degree-it-not-trouble} -} - Modified: pkg/quantstrat/sandbox/backtest_musings/strat_dev_process.Rmd =================================================================== --- pkg/quantstrat/sandbox/backtest_musings/strat_dev_process.Rmd 2016-04-09 13:18:05 UTC (rev 1747) +++ pkg/quantstrat/sandbox/backtest_musings/strat_dev_process.Rmd 2016-04-17 18:25:28 UTC (rev 1748) @@ -3,7 +3,7 @@ author: Brian G. Peterson bibliography: stat_process.bib output: - rmarkdown::tufte_handout + tufte::tufte_handout #tufterhandout::html_tufte_handout #toc: true #toc_depth: 2 @@ -12,8 +12,8 @@ keywords: quantitative trading, backtest, quantitative strategy, scientific method subject: quantitative trading, backtest, quantitative strategy, scientific method -footer: Copyright 2014 Brian G. Peterson CC-BY-NC-SA. -copyright: Copyright 2014 Brian G. Peterson CC-BY-NC-SA. +footer: Copyright 2014-2016 Brian G. Peterson CC-BY-NC-SA. +copyright: Copyright 2014-2016 Brian G. Peterson CC-BY-NC-SA. abstract: Analysts and portfolio managers face many challenges in developing new systematic trading systems. This paper provides a detailed, repeatable process to aid in evaluating new ideas, developing those ideas into testable hypotheses, measuring results in comparable ways, and avoiding and measuring the ever-present risks of over-fitting. ^[ *Back-testing. I hate it ?- it's just optimizing over history. You never see a bad back-test. Ever. In any strategy.* - Josh Diedesch[- at Diedesch2014] ] @@ -322,6 +322,14 @@ multiple times while the model is "refined", introducing progressively more data snooping bias. +Social scientists have coined the term HARKing[@Kerr1998] for "hypothesizing +after the results are known". This needs to be separated from true scientific +inference, which develops an **a priori** hypothesis from examining raw or +unmassaged data. Defining a hypothesis should proceed from data to question to +testable conjecture about a dependent variable. Rejecting a hypothesis is more +valuable that inventing one after the fact. (and avoids losing money on an random +or over-fit model) + ___ # Defining the strategy @@ -334,17 +342,18 @@ *filters*, *indicators*, *signals*, and *rules*. \newthought{Filters} help to select the instruments to trade. -They may be part of the formulated hypothesis, or they may be market -characteristics that allow the rest of the strategy to trade better. -In fundamental equity investing, some strategies consist only of filters. -For example, the StarMine package that was bought by Thomson Reuters defines -quantitative stock screens based on technicals or fundamentals.^[a modern, free -alternative may be found at http://finviz.com/screener.ashx] -Many analysts will expand or shrink their investible universe based on screens. -Lo's Variance Ratio is another measure often used as a filter to turn the -strategy on or off for particular instruments (but can also be used as an -indicator, since it is time-varying). +They may be part of the formulated hypothesis, or they may be market +characteristics that allow the rest of the strategy to trade better. In +fundamental equity investing, some strategies consist only of filters. For +example, the StarMine package that was bought by Thomson Reuters defines +quantitative stock screens based on technicals or fundamentals.^[a modern, free +alternative may be found at http://finviz.com/screener.ashx] Many analysts will +expand or shrink their investible universe based on screens. Lo's Variance Ratio +is another measure often used as a filter to turn the strategy on or off for +particular instruments (but can also be used as an indicator, since it is +time-varying). + \newthought{Indicators} are quantitative values derived from market data. Examples of indicators include moving averages, RSI, MACD, volatility bands, @@ -1115,7 +1124,7 @@ Flat to flat "trade" analysis marks the beginning of the trade from the first transaction to move the position off zero, and marks the end of - the "trade" with the transaction that brings the P\&L back to zero, + the "trade" with the transaction that brings the position back to zero, or "flat". It will match brokerage statements of realized P\&L when the positions is flat and average cost of open positions always, so it is easy to reconcile @@ -1157,9 +1166,14 @@ reduction to an increase, in expanding order from the first reduction. This is "time and quantity" priority, and is analytically more repeatable and manageable than FIFO. If you have a reason for utilizing FIFO-like - analysis, consider using "increased to reduced" instead. Be aware that the - "trade" statistics will not be reconcilable to any brokerage statement, - this is purely an analytical methodology. + analysis, consider using "increased to reduced" instead. This methodology + is sometimes called "average cost FIFO", and there is an average cost LIFO + variant as well. In contrast to traditional FIFO, realized P\&L on a + per-period basis will match the brokerage statements using this methodology, + as realized P\&L is taken from the same average cost basis. Be aware that + the round-turn "trade" statistics may not be fully reconcilable to a + brokerage statement, as the separation into round-turn "trades" is purely an + analytical methodology. \newthought{Aggregate trade statistics are calculated on the entire backtest.} @@ -1734,7 +1748,7 @@ ___ -?2014-2015 Brian G. Peterson +?2014-2016 Brian G. Peterson \includegraphics[width=1.75cm]{cc-by-nc-sa} Modified: pkg/quantstrat/sandbox/backtest_musings/strat_dev_process.pdf =================================================================== (Binary files differ)