[Blotter-commits] r1165 - in pkg/blotter: R man

noreply at r-forge.r-project.org noreply at r-forge.r-project.org
Sat Sep 8 15:45:01 CEST 2012


Author: braverock
Date: 2012-09-08 15:45:01 +0200 (Sat, 08 Sep 2012)
New Revision: 1165

Added:
   pkg/blotter/man/perTradeStats.Rd
Modified:
   pkg/blotter/R/chart.ME.R
   pkg/blotter/man/chart.ME.Rd
   pkg/blotter/man/extractTxns.Rd
Log:
- split chat.Me and perTradeStats into two functions
- fix open last trade to use mark at end of series
- remove $ symbols from chart, not all instruments are USD
- update documentation


Modified: pkg/blotter/R/chart.ME.R
===================================================================
--- pkg/blotter/R/chart.ME.R	2012-09-06 20:21:08 UTC (rev 1164)
+++ pkg/blotter/R/chart.ME.R	2012-09-08 13:45:01 UTC (rev 1165)
@@ -1,61 +1,28 @@
 #' Chart Maximum Adverse/Forward Excursion
 #'
-#' Produces a scatterplot with one point per trade, with x-axis: absolute value of Drawdown (Adverse), or RunUp (Favourable), and y-axis: absolute value of Net Profit or Loss
+#' Produces a scatterplot with one point per trade, with x-axis: absolute 
+#' value of Drawdown (Adverse), or RunUp (Favourable), 
+#' and y-axis: absolute value of Net Profit or Loss
 #'
-#' After Jaekle & Tomasini: Trading Systems - A new approach to system development and portfolio optimisation (ISBN 978-1-905641-79-6), paragraph 3.5
-#'
 #' @param Portfolio string identifying the portfolio to chart
 #' @param Symbol string identifying the symbol to chart. If missing, the first symbol found in the \code{Portfolio} portfolio will be used
 #' @param type string specifying MAE (Adverse) or MFE (Favourable) chart type
 #' @param scale string specifying 'cash', or 'percent' for percentage of investment
+#' @param \dots any other passthrough parameters
+#' @author Jan Humme
+#' @references Tomasini, E. and Jaekle, U. \emph{Trading Systems - A new approach to system development and portfolio optimisation} (ISBN 978-1-905641-79-6), section 3.5
 #' @export
-chart.ME <- function(portfolio, symbol, type=c('MAE', 'MFE'), scale=c('cash', 'percent'))
+chart.ME <- function(Portfolio, Symbol, type=c('MAE', 'MFE'), scale=c('cash', 'percent'),...)
 {   # @author Jan Humme
 
-    require(xts)
+    trades <- perTradeStats(Portfolio,Symbol)
+    
 
-    portf <- getPortfolio(portfolio)
-
-    if(missing(symbol)) symbol <- names(portf$symbols)[[1]]
+    #multiply Pcct numbers for prettier charting
+    trades$Pct.Net.Trading.PL <- 100 * trades$Pct.Net.Trading.PL
+    trades$Pct.Drawdown       <- 100 * trades$Pct.Drawdown
+    trades$Pct.RunUp          <- 100 * trades$Pct.RunUp
     
-    posPL <- portf$symbols[[symbol]]$posPL
-
-    trades <- list()
-
-    # identify start and end for each trade, where end means flat position
-    trades$Start <- index(posPL[which(posPL$Pos.Value!=0 & lag(posPL$Pos.Value)==0),])
-    trades$End <- index(posPL[which(posPL$Pos.Value==0 & lag(posPL$Pos.Value)!=0),])
-
-    # discard open last trade, if any
-    trades$Start <- trades$Start[1:length(trades$End)]
-
-    for(i in 1:length(trades$End))
-    {
-        timespan <- paste(format(trades$Start[[i]], "%Y-%m-%d %H:%M:%OS6"),
-                          format(trades$End[[i]], "%Y-%m-%d %H:%M:%OS6"), sep="::")
-
-        trade <- posPL[timespan]
-
-        # close and open may occur in at same index timestamp, must be corrected
-        if(first(trade)$Pos.Qty==0) trade <- tail(trade, -1)
-        if(last(trade)$Pos.Qty!=0) trade <- head(trade, -1)
-
-        # investment
-        trades$Txn.Value[i] <- abs(first(trade$Txn.Value))
-
-        # cash-wise
-        trades$Net.Trading.PL[i] <- sum(trade$Net.Trading.PL)
-        trades$Drawdown[i] <- min(0,cumsum(trade$Net.Trading.PL))
-        trades$RunUp[i] <- max(0,cumsum(trade$Net.Trading.PL))
-    }
-
-    # percentage-wise
-    trades$Pct.Net.Trading.PL <- 100 * trades$Net.Trading.PL / trades$Txn.Value
-    trades$Pct.Drawdown <- 100 * trades$Drawdown / trades$Txn.Value
-    trades$Pct.RunUp <- 100 * trades$RunUp / trades$Txn.Value
-
-    trades <- as.data.frame(trades)
-
     profitable <- (trades$Net.Trading.PL > 0)
 
     if(type == 'MAE')
@@ -63,8 +30,8 @@
         if(scale == 'cash')
         {
             plot(abs(trades[, c('Drawdown','Net.Trading.PL')]), type='n',
-                    xlab='Drawdown ($)', ylab='Profit (Loss) in $',
-                    main='Maximum Adverse Excursion (MAE) in $')
+                    xlab='Cash Drawdown', ylab='Cash Profit (Loss)',
+                    main='Maximum Adverse Excursion (MAE)')
 
             points(abs(trades[ profitable, c('Drawdown','Net.Trading.PL')]), pch=24, col='green', bg='green', cex=0.6)
             points(abs(trades[!profitable, c('Drawdown','Net.Trading.PL')]), pch=25, col='red', bg='red', cex=0.6)
@@ -84,8 +51,8 @@
         if(scale == 'cash')
         {
             plot(abs(trades[, c('RunUp','Net.Trading.PL')]), type='n',
-                    xlab='RunUp ($)', ylab='Profit (Loss) in $',
-                    main='Maximum Favourable Excursion (MFE) in $')
+                    xlab='Cash RunUp', ylab='Cash Profit (Loss)',
+                    main='Maximum Favourable Excursion (MFE)')
     
             points(abs(trades[ profitable, c('RunUp','Net.Trading.PL')]), pch=24, col='green', bg='green', cex=0.6)
             points(abs(trades[!profitable, c('RunUp','Net.Trading.PL')]), pch=25, col='red', bg='red', cex=0.6)
@@ -114,6 +81,89 @@
     )
 }
 
+#' calculate flat to flat per-trade statistics
+#'
+#' One 'trade' is defined as the entire time the symbol is not flat.
+#' It may contain many transactions.  From the initial transaction that
+#' moves the position away from zero to the last transaction that flattens the
+#' position is all one 'trade' for the purposes of this function.
+#' 
+#' This is sometimes referred to as 'flat to flat' analysis.
+#' 
+#' Note that a trade that is open at the end of the measured period will
+#' be marked to the timestamp of the end of the series.  
+#' If that trade is later closed, the stats for it will likely change. 
+#'  
+#' @param Portfolio string identifying the portfolio to chart
+#' @param Symbol string identifying the symbol to chart. If missing, the first symbol found in the \code{Portfolio} portfolio will be used
+#' @param \dots any other passthrough parameters
+#' @author Brian G. Peterson, Jan Hume
+#' @references Tomasini, E. and Jaekle, U. \emph{Trading Systems - A new approach to system development and portfolio optimisation} (ISBN 978-1-905641-79-6)
+#' @export
+perTradeStats <- function(Portfolio, Symbol,...) {
+    portf <- getPortfolio(Portfolio)
+    
+    if(missing(Symbol)) Symbol <- names(portf$symbols)[[1]]
+    
+    posPL <- portf$symbols[[Symbol]]$posPL
+    
+    trades <- list()
+    
+    # identify start and end for each trade, where end means flat position
+    trades$Start <- index(posPL[which(posPL$Pos.Value!=0 & lag(posPL$Pos.Value)==0),])
+    trades$End <- index(posPL[which(posPL$Pos.Value==0 & lag(posPL$Pos.Value)!=0),])
+    
+    # discard open last trade, if any
+    # trades$Start <- trades$Start[1:length(trades$End)]
+    #TODO FIXME if trade is still open at end of series, set end of open trade to the end of the series instead
+    if(length(trades$Start)>length(trades$End)){
+        trades$End <- c(trades$End,last(index(posPL)))
+    }
+    
+    # calculate information about each trade
+    for(i in 1:length(trades$End))
+    {
+        timespan <- paste(format(trades$Start[[i]], "%Y-%m-%d %H:%M:%OS6"),
+                format(trades$End[[i]], "%Y-%m-%d %H:%M:%OS6"), sep="::")
+        
+        trade <- posPL[timespan]
+        
+        # close and open may occur in at same index timestamp, must be corrected
+        if(first(trade)$Pos.Qty==0) trade <- tail(trade, -1)
+        if(last(trade)$Pos.Qty!=0) trade <- head(trade, -1)
+        
+        # investment
+        trades$Txn.Value[i] <- abs(first(trade$Txn.Value))
+        #TODO FIXME this is wrong for trades that level in/out, I think we need na.locf.
+        
+        #position sizes
+        trades$Max.Pos[i] <- trade[which(abs(trade$Pos.Qty)==max(abs(trade$Pos.Qty))),]$Pos.Qty
+        trades$Init.Pos[i] <- first(trade)$Pos.Qty
+        
+        #count number of transactions
+        
+        # cash-wise
+        trades$Net.Trading.PL[i] <- sum(trade$Net.Trading.PL)
+        trades$Drawdown[i] <- min(0,cumsum(trade$Net.Trading.PL))
+        trades$RunUp[i] <- max(0,cumsum(trade$Net.Trading.PL))
+    }
+    
+    # percentage-wise
+    trades$Pct.Net.Trading.PL <- trades$Net.Trading.PL / trades$Txn.Value
+    trades$Pct.Drawdown <- trades$Drawdown / trades$Txn.Value
+    trades$Pct.RunUp <- trades$RunUp / trades$Txn.Value
+
+    #TODO add tick stats
+
+    trades <- as.data.frame(trades)
+    return(trades)
+}
+
+# to algorithmically set stops, the classic answer is to calculate quantiles.
+# i'm not sure if this belongs in tradeStats, perhaps?  
+# perhaps include MFE and MAE stats in tradeStats, plus some quantile information
+# for MAE of the 90% and 95% quantiles of profitable trades?
+
 ###############################################################################
 # Blotter: Tools for transaction-oriented trading systems development
 # for R (see http://r-project.org/) 
@@ -122,6 +172,6 @@
 # This library is distributed under the terms of the GNU Public License (GPL)
 # for full details see the file COPYING
 #
-# $Id: chart.Posn.R 855 2011-11-28 23:41:46Z bodanker $
+# $Id$
 #
 ###############################################################################


Property changes on: pkg/blotter/R/chart.ME.R
___________________________________________________________________
Added: svn:keywords
   + Id Author Date

Modified: pkg/blotter/man/chart.ME.Rd
===================================================================
--- pkg/blotter/man/chart.ME.Rd	2012-09-06 20:21:08 UTC (rev 1164)
+++ pkg/blotter/man/chart.ME.Rd	2012-09-08 13:45:01 UTC (rev 1165)
@@ -2,8 +2,8 @@
 \alias{chart.ME}
 \title{Chart Maximum Adverse/Forward Excursion}
 \usage{
-  chart.ME(portfolio, symbol, type = c("MAE", "MFE"),
-    scale = c("cash", "percent"))
+  chart.ME(Portfolio, Symbol, type = c("MAE", "MFE"),
+    scale = c("cash", "percent"), ...)
 }
 \arguments{
   \item{Portfolio}{string identifying the portfolio to
@@ -18,6 +18,8 @@
 
   \item{scale}{string specifying 'cash', or 'percent' for
   percentage of investment}
+
+  \item{\dots}{any other passthrough parameters}
 }
 \description{
   Produces a scatterplot with one point per trade, with
@@ -25,9 +27,12 @@
   (Favourable), and y-axis: absolute value of Net Profit or
   Loss
 }
-\details{
-  After Jaekle & Tomasini: Trading Systems - A new approach
-  to system development and portfolio optimisation (ISBN
-  978-1-905641-79-6), paragraph 3.5
+\author{
+  Jan Humme
 }
+\references{
+  Tomasini, E. and Jaekle, U. \emph{Trading Systems - A new
+  approach to system development and portfolio
+  optimisation} (ISBN 978-1-905641-79-6), section 3.5
+}
 

Modified: pkg/blotter/man/extractTxns.Rd
===================================================================
--- pkg/blotter/man/extractTxns.Rd	2012-09-06 20:21:08 UTC (rev 1164)
+++ pkg/blotter/man/extractTxns.Rd	2012-09-08 13:45:01 UTC (rev 1165)
@@ -17,14 +17,15 @@
   calls for all the transactions in \code{Portfolio}. This
   is the fundamental task required to create a reproducible
   example, as it would replicate the state of the $txn slot
-  in the portfolio after each \code{addTxn} call. While
-  market data, expected results, portfolio and account
-  setup, etc, are also required, these can usually be
-  deduced or equivalent formulations can be found.
+  in the portfolio after each \code{addTxn} call.
 }
 \details{
+  While market data, expected results, portfolio and
+  account setup, etc, are also required, these can usually
+  be deduced or equivalent formulations can be found.
+
   For transactions, only the exact \code{addTxn} parameters
-  will recreate the $txn slot.  This function creates that
+  will recreate the $txn slot. This function creates that
   reproducibility, since the result (stored in 'x') can be
   used to regenerate transactions with
   \code{eval(parse(text=x))}.

Added: pkg/blotter/man/perTradeStats.Rd
===================================================================
--- pkg/blotter/man/perTradeStats.Rd	                        (rev 0)
+++ pkg/blotter/man/perTradeStats.Rd	2012-09-08 13:45:01 UTC (rev 1165)
@@ -0,0 +1,40 @@
+\name{perTradeStats}
+\alias{perTradeStats}
+\title{calculate flat to flat per-trade statistics}
+\usage{
+  perTradeStats(Portfolio, Symbol, ...)
+}
+\arguments{
+  \item{Portfolio}{string identifying the portfolio to
+  chart}
+
+  \item{Symbol}{string identifying the symbol to chart. If
+  missing, the first symbol found in the \code{Portfolio}
+  portfolio will be used}
+
+  \item{\dots}{any other passthrough parameters}
+}
+\description{
+  One 'trade' is defined as the entire time the symbol is
+  not flat. It may contain many transactions.  From the
+  initial transaction that moves the position away from
+  zero to the last transaction that flattens the position
+  is all one 'trade' for the purposes of this function.
+}
+\details{
+  This is sometimes referred to as 'flat to flat' analysis.
+
+  Note that a trade that is open at the end of the measured
+  period will be marked to the timestamp of the end of the
+  series. If that trade is later closed, the stats for it
+  will likely change.
+}
+\author{
+  Brian G. Peterson, Jan Hume
+}
+\references{
+  Tomasini, E. and Jaekle, U. \emph{Trading Systems - A new
+  approach to system development and portfolio
+  optimisation} (ISBN 978-1-905641-79-6)
+}
+



More information about the Blotter-commits mailing list