[Blotter-commits] r1663 - in pkg/quantstrat: . R demo man

noreply at r-forge.r-project.org noreply at r-forge.r-project.org
Wed Dec 31 14:19:06 CET 2014


Author: michaelguan326
Date: 2014-12-31 14:19:05 +0100 (Wed, 31 Dec 2014)
New Revision: 1663

Modified:
   pkg/quantstrat/DESCRIPTION
   pkg/quantstrat/NAMESPACE
   pkg/quantstrat/R/signals.R
   pkg/quantstrat/demo/00Index
   pkg/quantstrat/man/ruleOrderProc.Rd
Log:
New Signal Analysis Module

Modified: pkg/quantstrat/DESCRIPTION
===================================================================
--- pkg/quantstrat/DESCRIPTION	2014-12-26 20:13:24 UTC (rev 1662)
+++ pkg/quantstrat/DESCRIPTION	2014-12-31 13:19:05 UTC (rev 1663)
@@ -1,7 +1,7 @@
 Package: quantstrat
 Type: Package
 Title: Quantitative Strategy Model Framework
-Version: 0.9.1662
+Version: 0.9.1663
 Date: $Date$
 Author: Peter Carl, Brian G. Peterson, Joshua Ulrich, Jan Humme
 Depends:
@@ -14,12 +14,16 @@
     PortfolioAnalytics,
     rgl,
     testthat,
-    xtsExtra
+    xtsExtra,
+    rCharts,
+    gamlss.util,
+    reshape2,
+    beanplot
 Maintainer: Brian G. Peterson <brian at braverock.com>
 Description: Specify, build, and back-test quantitative
     financial trading and portfolio strategies
 Contributors: Yu Chen, Joe Dunn, Dirk Eddelbuettel,
-    Jeffrey A. Ryan, Garrett See
+    Michael Guan, Jeffrey A. Ryan, Garrett See
 LazyLoad: yes
 License: GPL-3
 ByteCompile: TRUE

Modified: pkg/quantstrat/NAMESPACE
===================================================================
--- pkg/quantstrat/NAMESPACE	2014-12-26 20:13:24 UTC (rev 1662)
+++ pkg/quantstrat/NAMESPACE	2014-12-31 13:19:05 UTC (rev 1663)
@@ -1,5 +1,6 @@
 # Generated by roxygen2 (4.0.2): do not edit by hand
 
+S3method(plot,signal.path)
 export(add.distribution)
 export(add.distribution.constraint)
 export(add.indicator)
@@ -9,6 +10,7 @@
 export(addOrder)
 export(addPosLimit)
 export(apply.paramset)
+export(apply.paramset.signal.analysis)
 export(applyIndicators)
 export(applyRules)
 export(applySignals)

Modified: pkg/quantstrat/R/signals.R
===================================================================
--- pkg/quantstrat/R/signals.R	2014-12-26 20:13:24 UTC (rev 1662)
+++ pkg/quantstrat/R/signals.R	2014-12-31 13:19:05 UTC (rev 1663)
@@ -371,6 +371,575 @@
    return(ret)
 }
 
+#' Signal Analysis With Parmeter Optimization
+#' 
+#' This function allows user to analyze signals independently from rules.
+#' 
+#' This function is similar to \code{applyParameter} but includes additionally \code{applySignal} wrapped within it. To use it, the user 
+#' will need to initially define the distribution and constraints by using \code{add.distribution} and \code{add.distribution.constraint}.
+#' 
+#' More generally, the function is designed to generate signals across various parameter combinations defined within the distribution and
+#' constraints. Afterwards it extract the next N day price changes for further anlaysis.
+#' 
+#' The parameter \code{on} allows user to calculate post signal returns in different frequencies. Different signals have different timeframes effectiveness. 
+#' \code{forward.days} lets the user select the number of post signal days to analyze results. 
+#' 
+#' To determine the goodness of a parameter set relative to all others, we let the user specify their own objective function (via parameter \code{obj.func})
+#' that will be used to calculate an objective value representing each parameter. These will then be sorted from best to worst. The
+#' objective function will take in a single matrix \code{ret.mat} of price changes. Each row represents an individual signal
+#' while each column represents periods/post signal. 
+#' 
+#' See demo 'signalAnalysisExample1.R' & 'signalAnalysisExample2.R'
+#' 
+#' @param strategy.st an object of type 'strategy' to add the indicator to
+#' @param paramset.label a label uniquely identifying the paramset within the strategy
+#' @param portfolio.st text name of the portfolio to associate the order book with
+#' @param sigval signal value to match against
+#' @param sigcol column name to check for signal
+#' @param on the periods endpoints to find as a character string 
+#' @param forward.days days to exit post signal
+#' @param cum.sum whether to use cumsum on price changes
+#' @param include.day.of.signal whether to include the day of signal generation
+#' @param obj.fun objective function for determining goodness of each paramset
+#' @param decreasing how to sort the obj.fun output values
+#' @param mktdata market data
+#' @param verbose whether to output processing messages
+#' @author Michael Guan
+#' @return
+#' A list of objects that contains the results
+#' \describe{
+#'    \item{signals}{List of signals named by parameter combination. Each object within the list is a XTS object with columns being assets and rows being signals.}
+#'    \item{sigret.by.paramset}{List of list. Sorted by parameter combination and then by asset. Contains matrix of next day returns; columns are period (N day look ahead) and rows are signals}
+#'    \item{sigret.by.asset}{List of list. Sorted by Asset and then by parameter combinations. Contains same matrix as sigret.by.paramset}
+#'    \item{signal.stats}{List of signal statistics as calculated via custom user defined fitness function. Sorted by assets.}
+#' }
+#' @seealso 
+#' \code{\link{add.distribution}}
+#' \code{\link{add.distribution.constraint}}
+#' @export
+
+apply.paramset.signal.analysis<-function(strategy.st, paramset.label, portfolio.st, sigcol,sigval,
+                                         on,forward.days,cum.sum=TRUE,include.day.of.signal,
+                                         obj.fun,decreasing,mktdata=NULL,verbose=TRUE){
+  
+  must.have.args(match.call(), c('strategy.st', 'paramset.label', 'portfolio.st')) #
+  
+  strategy <- must.be.strategy(strategy.st) 
+  must.be.paramset(strategy, paramset.label)   
+  portfolio <- .getPortfolio(portfolio.st)
+  
+  distributions <- strategy$paramsets[[paramset.label]]$distributions
+  constraints <- strategy$paramsets[[paramset.label]]$constraints
+  
+  param.combos <- expand.distributions(distributions)
+  param.combos <- apply.constraints(constraints, distributions, param.combos)
+  rownames(param.combos) <- NULL  # reset rownames
+  
+  symbols = ls(portfolio$symbols)
+  
+  # list()
+  # ...$ Paramset1 Signals = xts object; columns = by asset
+  # ...$ Paramset2 Signals = xts object; columns = by asset
+  .sig.list<-list() #list of signals as xts objects, each element in list contains n columns of signals for each asset in universe
+  
+  
+  # list() by paramset
+  # ...$ Paramset1
+  #     ...$ Asset1
+  #     ...$ Asset2
+  # ...$ Paramset2
+  #     ...$ Asset1
+  #     ...$ Asset2
+  .sig.ret.by.paramset = list() 
+  
+  # list() by asset
+  # ...$ Asset1:
+  #     ...paramset1
+  #     ...paramset2
+  # ...$ Asset2:
+  #     ...$ paramset1
+  #     ...$ paramset2
+  .sig.ret.by.asset = list() 
+  for(sym in symbols) .sig.ret.by.asset[[sym]] = list()
+  
+  # Loop through parameter by row to get signals
+  #   Loop through each symbol
+  # TODO: parallelize it
+  for(i in 1:nrow(param.combos)){  # param.combo = param.combos[1,]
+    param.combo = param.combos[i,]
+    
+    if(verbose)cat("Applying Parameter Set: ",toString(param.combo),'\n')  
+    
+    # Attached Paramset to Strategy Object
+    strategy <- quantstrat:::install.param.combo(strategy, param.combo, paramset.label) 
+    
+    # Generate Indicators and Signals for Given Paramset
+    name.ref = paste('paramset.',gsub(", ",".",toString(param.combo)),sep='')
+    .sig.list[[name.ref]] = applyIndicatorSignals(strategy, portfolio.st, mktdata, sigcol)
+    
+    # Construct Post Signal Returns, loop through signal for each asset
+    signal.ret.list.by.asset <- list() # post signal returns by asset
+    for(j in 1:length( symbols  )){
+      
+      # Extract Post Signal Price Deltas for Given Asset Signals [can't do apply() here, unless force a dim on it inside function]
+      signal.ret.list.by.asset[[symbols[j]]] = post.signal.returns(signals=.sig.list[[name.ref]][,paste(symbols[j],'.signal',sep='')],
+                                                                   sigval=sigval,on=on,forward.days=forward.days,
+                                                                   cum.sum=cum.sum,include.day.of.signal=include.day.of.signal)
+      
+      # Store Post Signal Price Deltas for Given Asset
+      .sig.ret.by.asset[[symbols[j]]][[name.ref]] = signal.ret.list.by.asset[[symbols[j]]]
+    }
+    
+    # Store Post Signal Price Deltas for Given Paramset
+    .sig.ret.by.paramset[[name.ref]] = signal.ret.list.by.asset
+  }
+  
+  # Generate Statistics by Asset
+  signal.stats<-list()
+  for(sym in symbols){
+    signal.stats[[sym]] = signal.generate.statistics(post.ret=.sig.ret.by.asset[[sym]], obj.fun=obj.fun, decreasing=decreasing)
+  }
+  
+  results = list()
+  results$signals = .sig.list
+  results$sigret.by.paramset = .sig.ret.by.paramset
+  results$sigret.by.asset = .sig.ret.by.asset
+  results$signal.stats = signal.stats
+  return(results)
+}
+
+#' Calculate Indicators and Signals for a Strategy
+#'
+#' Calculate signals given indicators and signal definitions.
+#'
+#' @param strategy an object (or the name of an object) type 'strategy' to add the indicator to
+#' @param portfolio text name of the portfolio to associate the order book with
+#' @param mktdata market data
+#' @param sigcol String name of signal to use for analysis 
+#' @author Michael Guan
+#' @return \code{xts} object with columns representing signals for each symbol
+#' @seealso 
+#' \code{\link{apply.paramset.signal.analysis}}
+#' \code{\link{applyIndicators}}
+#' \code{\link{applySignals}}
+
+applyIndicatorSignals<-function(strategy, portfolio, mktdata, sigcol, ...){
+  
+  # Get Portfolio & Symbols
+  pobj <- .getPortfolio(portfolio)
+  symbols <- ls(pobj$symbols)
+  
+  # Loop Through asset by asset and combine signal columns in to single xts object
+  .signals<-c()
+  for(symbol in symbols){ 
+    mktdata <- get(symbol) #get market data for current iteration symbol
+    
+    # Apply Indicators and Signals for Given Asset
+    temp <- applyIndicators(strategy = strategy, mktdata = mktdata, ...)
+    temp <- applySignals(strategy = strategy, mktdata = temp, ...)
+    
+    sig.col = temp[,sigcol]
+    sig.col[which(is.na(sig.col) == TRUE),] = 0
+    colnames(sig.col) <- paste(symbol,'.signal',sep='')
+    .signals = merge.xts(.signals,sig.col)    #cbind,merge.xts,or merge? 
+  }
+  
+  return(.signals)
+}
+
+
+#' Signal Objective Function Calculation
+#'
+#' This function takes a list of matrix of post signal price changes and 
+#' applies an user defined objective function on it. 
+#'                           
+#' @param post.ret \code{matrix} of parameter set of post signal price deltas
+#' @param obj.fun custom objective function for measuring signal goodness
+#' @param decreasing if true, the higher the objective value, the better
+#' @author Michael Guan
+#' @return objective function values
+#' @seealso 
+#' \code{\link{apply.paramset.signal.analysis}}
+
+signal.generate.statistics<-function(post.ret, obj.fun=NULL, decreasing=TRUE){
+  if(is.null(obj.fun)) stop("Must define an objective function for signal sorting.")
+  obj.fun = match.fun(obj.fun)
+  results = list()
+  obj.values = matrix(NA,nrow=length(post.ret),ncol=1)
+  row.names = c()
+  
+  for(j in 1:length(names(post.ret))){
+    obj.value = obj.fun(post.ret[[names(post.ret)[j]]])
+    if(length(obj.value)!=1) stop('Custom objective function must return only a single value.')
+    obj.values[j,]=obj.value
+    row.names=c(row.names,names(post.ret)[j])
+  }
+  rownames(obj.values) = row.names
+  
+  results[['obj']] = apply(obj.values,2,sort,decreasing=decreasing) #Sort
+  
+  return(results)
+}
+
+
+#' Generate Post Signal Returns
+#'
+#' This function collects and aggregates post signal price changes for N days forward.
+#' 
+#' @param signals xts object with signals, one column
+#' @param sigvals signal value to match against
+#' @param on the periods endpoints to find as a character string
+#' @param forward.days number of days to look forward after signal (days to exit post signal)
+#' @param cum.sum \code{TRUE},\code{FALSE}; cumulative sum of price changes
+#' @param include.day.of.signal whether to analyze the return on signal day
+#' @param mktdata market data
+#' @author Michael Guan
+#' @return \code{matrix} of post signal price changes; rows = nth signal, column = nth period since signal
+#' @seealso 
+#' \code{\link{apply.paramset.signal.analysis}}
+
+post.signal.returns<-function(signals,sigval,on=NULL,forward.days,cum.sum=TRUE,
+                              include.day.of.signal=FALSE,mktdata=NULL){
+  
+  # Incremental Index Values / Label Generation
+  if(include.day.of.signal == TRUE){
+    days.increment = c(0,seq(1,forward.days))
+    name.ref = sapply( days.increment ,function(x){paste("Period",x,sep='.')})
+  }else{
+    days.increment = seq(1,forward.days+1)
+    name.ref = sapply( days.increment[-length(days.increment)] ,function(x){paste("Period",x,sep='.')})
+  }
+  
+  # Get Relevant Market Data
+  if(is.null(mktdata)){
+    symbol = gsub('.signal','',colnames(signals))
+    mktdata = get(symbol)
+  }
+  
+  if(!is.null(on)){
+    # Determine Number of Periods in Given Frequency ie) 1 week has 5 days if signal frequency = days
+    days.in.period = cbind(na.omit(signals),na.omit(signals)[endpoints(na.omit(signals),on),])[,2]
+    days.in.period[which(days.in.period == 0),] = 1
+    days.in.period[is.na(days.in.period),]=0
+    days.in.period = max(rle(as.vector(days.in.period))$lengths) + 1
+  }else{
+    days.in.period = 1
+  }
+  
+  # Get Price Delta 
+  ret = tryCatch({
+    ret = diff(Cl(mktdata))
+  }, error = function(e){
+    stop('Market Data does not contain a row with Close. Try to set and aggregate data on to a higher frequency.')
+  })
+  ret[1,] = 0
+  
+  # Align Mkt Data and Signals
+  signals = signals[index(ret),]
+  # Get Indexes of Signals
+  idx = which(as.vector(signals)==sigval)
+  
+  # Take out signals that cause "out of bounds" exception
+  idx.cancel = idx[which((nrow(signals) - idx) < max((days.increment * days.in.period)))]
+  if(length(idx.cancel)!=0){
+    signals[idx.cancel,]=0  
+    idx = idx[-which(idx %in% idx.cancel)]  
+  }
+  
+  if(length(idx) == 0)stop("There are no signals for analysis. Try reducing the number of look ahead periods.")
+  
+  # Daily return since signal; each column = days since signal; each row = each signal
+  signal.ret = matrix(NA,nrow=length(idx),ncol=length(name.ref)) #daily return since signal
+  
+  # Extract Returns
+  for(j in 1:length(idx)){
+    
+    signal.ret[j,] = tryCatch({
+      na.omit(diff(mktdata[idx[j] + (days.increment * days.in.period)  ,4]))
+    }, error = function(e){
+      cat('')
+      stop('Not enough forward data to evaluate post signal returns.')
+    })
+  }
+  
+  colnames(signal.ret) = name.ref
+  
+  if(cum.sum == TRUE) signal.ret = t(apply(signal.ret,1,cumsum)) # cumulative sum of price changes yields equity drift
+  #matplot(signal.ret,type='l')
+  return(signal.ret)
+}
+
+
+
+# post.signal.returns<-function(signals,sigval,on='weeks',forward.days,cum.sum=TRUE,
+#                               include.day.of.signal=FALSE,mktdata=NULL){
+#   
+#   # Get Relevant Market Data
+#   if(is.null(mktdata)){
+#     symbol = gsub('.signal','',colnames(signals))
+#     mktdata = get(symbol)
+#   }
+#   
+#   # Transform Market data to Specific Frequency 
+#   if(!is.null(on)){
+#     # Find the Dates for Mktdata in the frequency of interest
+#     # Find the Dates of Signals, merge the two to get the final dates of interest
+#     
+#     sig.date.idx = index(signals)[which(signals == sigval)]  
+#     mktdata.temp = mktdata[endpoints(x=mktdata,on=on),]
+#     
+#     mktdata.idx = index(cbind(mktdata.temp,signals))
+#     mktdata = mktdata[mktdata.idx,]
+#     signals = signals[mktdata.idx,]
+#   }
+#   
+#   # Get Price Delta 
+#   ret = tryCatch({
+#     ret = diff(Cl(mktdata))
+#   }, error = function(e){
+#     stop('Market Data does not contain a column with Close. Try to set and aggregate data on to a higher frequency.')
+#   })
+#   ret[1,] = 0
+#   
+#   # Align Mkt Data and Signals
+#   signals = signals[index(ret),]
+#   
+#   # Take out signals that cause "out of bounds" exception
+#   signals[(nrow(signals)-forward.days):nrow(signals),]=0  
+#   
+#   # Get Indexes of Signals
+#   idx = which(as.vector(signals)==sigval)
+#   
+#   if(length(idx) == 0) stop("There are no signals for analysis.")
+#   
+#   # Incremental Index Values / Label Generation
+#   if(isTRUE(include.day.of.signal)){
+#     days.increment = c(0,seq(1,forward.days))
+#     name.ref = sapply( days.increment ,function(x){paste("Period",x,sep='.')})
+#   }else{
+#     days.increment = seq(1,forward.days)
+#     name.ref = sapply( days.increment ,function(x){paste("Period",x,sep='.')})
+#   }
+#   
+#   # Daily return since signal; each column = days since signal; each row = each signal
+#   signal.ret = matrix(NA,nrow=length(idx),ncol=length(name.ref)) #daily return since signal
+#   
+#   # Extract return 
+#   for(j in 1:length(idx))signal.ret[j,] = ret[idx[j] + days.increment  ,]
+#   
+#   colnames(signal.ret) = name.ref
+#   
+#   if(isTRUE(cum.sum)) signal.ret = t(apply(signal.ret,1,cumsum)) # cumulative sum of price changes yields equity drift
+#   
+#   return(signal.ret)
+# }
+
+
+#' Signal Objective Function
+#' 
+#' Simple example of objective function that can can be used to measure the effectiveness of various parameter combinations.
+#' 
+#' Calculates the slope of the Cumulative Equity line. Higher the better.
+#' 
+#' It is important to note that all objective functions are called within \code{signal.generate.statistics}. What gets
+#' passed in to it as parameter is an matrix of post signal price changes or cumulative equity for each signal. The matrix
+#' is of N-by-M dimensions. N being the row representing the Nth signal. M being the column representing Mth period.  
+#' 
+#' @param x Return matrix, each row represents price deltas for a single signal, each column represents periods
+#' @author Michael Guan
+#' @return Single Objective Value
+#' @seealso 
+#' \code{\link{apply.paramset.signal.analysis}}
+
+signal.obj.slope<-function(x){
+  mu = colMeans(x)
+  lm.r = lm(mu~seq(length(mu))) 
+  obj = coef(lm.r)[2]
+  return(obj)
+}
+
+
+#' Visualization of Signal Across Lookback
+#'
+#' This function takes a list of  matrix of post signal price changes and 
+#' plots boxplots. Note function plots whatever is given to it therefore when 
+#' there are lots paramsets, it is best to plot a smaller portion so the 
+#' information can be displayed clearly.
+#'                          
+#' @param signal list of paramset forward looking price changes by asset
+#' @param rows number of rows for plot
+#' @param columns number of columns for plot
+#' @param mai A numerical vector of the form c(bottom, left, top, right) which gives the margin size specified in inches.
+#' @param mgp The margin line (in mex units) for the axis title, axis labels and axis line. Note that mgp[1] affects title whereas mgp[2:3] affect axis. The default is c(3, 1, 0).
+#' @param xlab a title for the x axis
+#' @param ylab a title for the y axis
+#' @param cex.main The magnification to be used for main titles relative to the current setting of cex.
+#' @param xaxt A character which specifies the x axis type. Specifying "n" suppresses plotting of the axis. The standard value is "s": for compatibility with S values "l" and "t" are accepted but are equivalent to "s": any value other than "n" implies plotting.
+#' @param cex.axis The magnification to be used for axis annotation relative to the current setting of cex.
+#' @param h the y-value(s) for horizontal line(s).
+#' @param hlinecol A specification for the default plotting color. See section ‘Color Specification’.
+#' @author Michael Guan
+#' @return plot
+#' 
+
+plot.signals<-function(signals,rows=NULL,columns=NULL,mai = c(0.1,0.4,0.2,0.1), mgp = c(1,1,0),
+                       xlab='',ylab='',cex.main=0.6,xaxt='n',cex.axis=0.5,h=0,hlinecol='red',...){
+  
+  if(is.null(signals)) stop('No signals to plot')
+  
+  # Determine Plot layout
+  if(is.null(rows) | is.null(columns)){
+    list.len = length(signals)
+    rows = ceiling(list.len / as.numeric(substring(toString(list.len),1,1)))
+    columns = ceiling(list.len / rows)  
+  }
+  
+  # Set up display parameters
+  plt = par(mfrow=c(rows,columns),mai=mai,mgp=mgp)
+  
+  # Generate Boxplot for each paramset
+  for(plt in names(signals)){
+    boxplot(x=signals[[plt]],main=plt,xlab=xlab,ylab=ylab,
+            cex.main=cex.main,xaxt=xaxt,cex.axis=cex.axis,...)
+    abline(h=h,col=hlinecol)
+  }
+  
+}
+
+#' Visualization of Signal Across Lookback with Beanplots
+#'
+#' This function is similar to \code{plot.signals} but uses beanplots 
+#' instead of barplots. Requires 'beanplot' package
+#'                          
+#' @param signal list of paramset forward looking price changes by asset
+#' @param rows number of rows for plot
+#' @param columns number of columns for plot
+#' @param mai A numerical vector of the form c(bottom, left, top, right) which gives the margin size specified in inches.
+#' @param mgp The margin line (in mex units) for the axis title, axis labels and axis line. Note that mgp[1] affects title whereas mgp[2:3] affect axis. The default is c(3, 1, 0).
+#' @param xlab a title for the x axis
+#' @param ylab a title for the y axis
+#' @param cex.main The magnification to be used for main titles relative to the current setting of cex.
+#' @param xaxt A character which specifies the x axis type. Specifying "n" suppresses plotting of the axis. The standard value is "s": for compatibility with S values "l" and "t" are accepted but are equivalent to "s": any value other than "n" implies plotting.
+#' @param cex.axis The magnification to be used for axis annotation relative to the current setting of cex.
+#' @param h the y-value(s) for horizontal line(s).
+#' @param hlinecol A specification for the default plotting color. See section ‘Color Specification’.
+#' @author Michael Guan
+#' @return plot
+ 
+beanplot.signals<-function(signals,rows=NULL,columns=NULL,mai = c(0.1,0.4,0.2,0.1), mgp = c(1,1,0),
+                           xlab='',ylab='',cex.main=0.6,xaxt='n',cex.axis=0.5,
+                           h=0,hlinecol='red',...){
+  require(beanplot)
+  
+  if(is.null(signals)) stop('No signals to plot')
+
+  # Determine Plot layout
+  if(is.null(rows) | is.null(columns)){
+    list.len = length(signals)
+    rows = ceiling(list.len / as.numeric(substring(toString(list.len),1,1)))
+    columns = ceiling(list.len / rows)  
+  }
+  
+  plt = par(mfrow=c(rows,columns),mai=mai,mgp=mgp)
+  
+  for(plt in names(signals)){
+    beanplot(data.frame(signals[[plt]]),xlab=xlab,ylab=ylab,main=plt,
+             cex.main = cex.main,xaxt=xaxt,cex.axis=cex.axis,...)
+    abline(h=h,col=hlinecol)
+  }
+}
+
+
+#' Visualization of Single Signal 
+#' 
+#' This function employs \code(plotSimpleGamlss) in package \code(gamlss.util).
+#'                          
+#' @param signal list of paramset forward looking price changes by asset
+#' @param x.val he values of the explanatory variable where we want to see the distribution
+#' @param val this parameter determines how the plotted distribution is shown, increase/decrease it if the distribution is not shown properly
+#' @param ylim the y limits in the plot
+#' @param xlim the x limits in the plot
+#' @param mai A numerical vector of the form c(bottom, left, top, right) which gives the margin size specified in inches.
+#' @param h the y-value(s) for horizontal line(s).
+#' @author Michael Guan
+#' @return plot
+
+distributional.boxplot<-function(signal,x.val=seq(1, 50, 5),val=10,ylim=c(-5, 5),
+                                 xlim=c(0, 50),mai=c(1,1,0.3,0.5),h=0,...){
+  
+  if(is.null(signal)) stop('No signals to plot')
+  if(!isTRUE("gamlss" %in% rownames(installed.packages()))) stop('Please install gamlss')
+  if(!isTRUE("gamlss.util" %in% rownames(installed.packages()))) stop('Please install gamlss.util')
+  
+  require(gamlss.util)
+  require(gamlss)
+  
+  # Reformat data
+  n.row = nrow(signal)
+  ind.var = matrix(signal)
+  dep.var = signal * NA
+  for(i in 1:ncol(dep.var)) dep.var[,i] = i
+  dep.var = matrix(dep.var)
+  
+  mat.data = cbind(dep.var,ind.var)
+  colnames(mat.data) = c('Period','Change')
+  mat.data = data.frame(mat.data)
+  par(mai=mai)
+  
+  # Regression
+  m1 <- gamlss(Change~Period, data=mat.data)
+  
+  # Visualization
+  tryCatch({
+    plotSimpleGamlss(y=Change,x=Period, model=m1,data=mat.data, 
+                     x.val=x.val, # where to plot the dist
+                     val=val, # size of dist
+                     ylim=ylim, xlim=xlim)
+    abline(h=0,lty=3,...)  
+  },error=function(e){cat('gamlss package currently doesnt 
+                            support encapsulation of their 
+                            plotting function. Pending Patch. \n')})
+    
+}
+
+#' Visualization of Signal Path
+#' 
+#' This function creates a rChart - hplot that is interactive. It displays 
+#'                          
+#' @param data signal data
+#' @param main plot title
+#' @author Michael Guan
+#' @return plot
+#' @examples
+#' \dontrun{
+#' # signalAnalysisExample1.R
+#' plot.signal.path(results$sigret.by.asset$RTH$paramset.1.5[1:10,])
+#' }
+#' @export
+plot.signal.path<-function(data,main='Cumulative Return Paths'){
+  require(rCharts) #TODO: Need to wrap around If statement
+  require(reshape2)
+  data = t(data)
+  n.row = nrow(data)
+  ind.var = matrix(data)
+  dep.var = ind.var * NA
+  dep.var[] = rep(seq(1,n.row,1),ncol(data))
+  
+  groups = ind.var * NA
+  groups[]=melt(sapply( seq(1,ncol(data),1),function(x)rep(x,n.row)))[,2]
+  
+  
+  mat = cbind(dep.var,ind.var,groups)
+  colnames(mat) = c('Periods','Returns','groups')
+  mat = data.frame(mat)
+  h2a = hPlot(x = "Periods", y = "Returns",group='groups', data = mat, 
+              type = "line",showInLegend = FALSE,title=main)
+  
+  h2a$legend(FALSE)
+  h2a
+}
+
+
 #TODO Going Up/Going Down maybe better implemented as slope/diff() indicator, then coupled with threshold signal 
 #TODO set/reset indicator/signal for n-periods since some other signal is set, or signal set for n periods
 

Modified: pkg/quantstrat/demo/00Index
===================================================================
--- pkg/quantstrat/demo/00Index	2014-12-26 20:13:24 UTC (rev 1662)
+++ pkg/quantstrat/demo/00Index	2014-12-31 13:19:05 UTC (rev 1663)
@@ -26,3 +26,5 @@
 luxor.sample.MFE.takeprofit.R	Jaekle & Tomasini; sample MFE take profit graph
 luxor.sample.tradeGraphs.sma.R	Jaekle & Tomasini; sample 3D SMA graph
 luxor.sample.tradeGraphs.timespan.R	Jaekle & Tomasini; sample 3D timespan graph
+signal.SMA.R	SMA Cross Strategy with Signal Analysis Example; See maCross.R
+signal.RSI.R	RSI Cross Strategy with Signal Analysis Example; See rsi.R
\ No newline at end of file

Modified: pkg/quantstrat/man/ruleOrderProc.Rd
===================================================================
--- pkg/quantstrat/man/ruleOrderProc.Rd	2014-12-26 20:13:24 UTC (rev 1662)
+++ pkg/quantstrat/man/ruleOrderProc.Rd	2014-12-31 13:19:05 UTC (rev 1663)
@@ -5,9 +5,6 @@
 \usage{
 ruleOrderProc(portfolio, symbol, mktdata, timestamp = NULL,
   ordertype = NULL, ..., slippageFUN = NULL)
-
-ruleOrderProc(portfolio, symbol, mktdata, timestamp = NULL,
-  ordertype = NULL, ..., slippageFUN = NULL)
 }
 \arguments{
 \item{portfolio}{text name of the portfolio to associate the order book with}
@@ -23,31 +20,12 @@
 \item{...}{any other passthru parameters}
 
 \item{slippageFUN}{default  NULL, not yet implemented}
-
-\item{portfolio}{text name of the portfolio to associate the order book with}
-
-\item{symbol}{identfier of the instrument to find orders for.  The name of any associated price objects (xts prices, usually OHLC or BBO) should match these}
-
-\item{mktdata}{an xts object containing market data.  depending on indicators, may need to be in OHLCV or BBO formats, default NULL}
-
-\item{timestamp}{timestamp coercible to POSIXct that will be the time the order will be processed on}
-
-\item{ordertype}{one of NULL, "market","limit","stoplimit", or "stoptrailing" default NULL}
-
-\item{...}{any other passthru parameters}
-
-\item{slippageFUN}{default  NULL, not yet implemented}
 }
 \description{
 The ruleOrderProc function is effectively the default fill simulator for quantstrat.
 This function is meant to be sufficient for backtesting most strategies,
 but would need to be replaced for production use.  It provides the interface
 for taking the order book and determining when orders become trades.
-
-The ruleOrderProc function is effectively the default fill simulator for quantstrat.
-This function is meant to be sufficient for backtesting most strategies,
-but would need to be replaced for production use.  It provides the interface
-for taking the order book and determining when orders become trades.
 }
 \details{
 In this version, in contrast with an earlier version,
@@ -71,28 +49,6 @@
 
 We would like to model slippage here via \code{slippageFUN}.  Code contributions, suggestions,
 and requests appreciated.
-
-In this version, in contrast with an earlier version,
-this function will allow a transaction to cross your current
-position through zero.  The accounting rules for realizing gains in such cases
-are quite complicated, so blotter will split this transaction into two transactions.
-Many brokers will break, revise, or split such transactions for the same reason.
-
-This function would need to be revised or replaced for connection to a live trading infrastructure.
-In a production mode, you would replace the \code{\link{addOrder}} function
-with a custom function to connect to your market infrastructure.
-In that case, you might need to add additional code to your strategy,
-or overload functions for checking position.
-
-Note that this function is called by default in the 'orders' slot of the
-\code{\link{applyRules}} processing.  If you have defined another order
-processing rule, it will \emph{replace} this function.  If you want your
-custom order rule and ruleOrderProc to both be called, you will need
-explicitly add a rule to call ruleOrderProc either before or after your
-custom order processing function.
-
-We would like to model slippage here via \code{slippageFUN}.  Code contributions, suggestions,
-and requests appreciated.
 }
 \seealso{
 add.rule
@@ -104,16 +60,6 @@
 addOrder
 
 updateOrders
-
-add.rule
-
-applyRules
-
-getOrderBook
-
-addOrder
-
-updateOrders
 }
 \concept{
 fill simulator
@@ -127,17 +73,5 @@
 This function is meant to be sufficient for backtesting many/most strategies,
 but would need to be replaced for production use.  It provides the interface
 for taking the order book and determining when orders become trades.
-
-fill simulator
-
-orders
-
-backtest
-
-fills
-
-This function is meant to be sufficient for backtesting many/most strategies,
-but would need to be replaced for production use.  It provides the interface
-for taking the order book and determining when orders become trades.
 }
 



More information about the Blotter-commits mailing list