pennyPerShare quantstrat not working

夙愿已清 提交于 2019-12-07 20:13:03

问题


When I use:

stratRank <- add.rule(stratRank, name="ruleSignal", 
             arguments=list(sigcol="EntryCond", sigval=TRUE, orderqty=max.size, 
             ordertype="market", orderside="long", pricemethod="market",
             replace=FALSE,osFUN=osMaxPos,TxnFees=pennyPerShare), type="enter")


  stratRank <- add.rule(stratRank, name="ruleSignal", 
               arguments=list(sigcol="ExitCond", sigval=TRUE, orderqty="all",
               ordertype="market", orderside="long", pricemethod="market",
               replace=FALSE,TxnFees=pennyPerShare), type="exit")

I get an error:

Error in `[.xts`(ordersubset, , "Order.Status") : unsupported type

I thought that pennyPerShare function is possible to add? Am I doing something wrong?

Note, that works, if I use static transaction costs:

stratRank <- add.rule(stratRank, name="ruleSignal", 
             arguments=list(sigcol="EntryCond", sigval=TRUE, orderqty=max.size, 
             ordertype="market", orderside="long", pricemethod="market",
             replace=FALSE,osFUN=osMaxPos,TxnFees=-5), type="enter")


  stratRank <- add.rule(stratRank, name="ruleSignal", 
               arguments=list(sigcol="ExitCond", sigval=TRUE, orderqty="all",
               ordertype="market", orderside="long", pricemethod="market",
               replace=FALSE,TxnFees=-5), type="exit")

And session info: for the currect set up. Greatful for any suggestions. Best Regards

sessionInfo()
R version 3.0.2 (2013-09-25)
Platform: x86_64-w64-mingw32/x64 (64-bit)

locale:
[1] LC_COLLATE=Swedish_Sweden.1252  LC_CTYPE=Swedish_Sweden.1252    LC_MONETARY=Swedish_Sweden.1252
[4] LC_NUMERIC=C                    LC_TIME=Swedish_Sweden.1252    

attached base packages:
[1] graphics  grDevices utils     datasets  stats     methods   base     

other attached packages:
 [1] quantstrat_0.8.2           foreach_1.4.1              blotter_0.9.1644           PerformanceAnalytics_1.1.0
 [5] FinancialInstrument_1.1.9  quantmod_0.4-0             TTR_0.22-0.1               Defaults_1.1-1            
 [9] xts_0.9-7                  zoo_1.7-10                 ggplot2_0.9.3.1           

loaded via a namespace (and not attached):
 [1] codetools_0.2-8    colorspace_1.2-3   dichromat_2.0-0    digest_0.6.3       fBasics_3010.86   
 [6] fGarch_3010.82     grid_3.0.2         gtable_0.1.2       iterators_1.0.6    labeling_0.2      
[11] lattice_0.20-23    MASS_7.3-29        munsell_0.4.2      plyr_1.8           proto_0.3-10      
[16] rCharts_0.4.2      RColorBrewer_1.0-5 reshape2_1.2.2     RJSONIO_1.0-3      ROAuth_0.9.3      
[21] scales_0.2.3       stabledist_0.6-6   stringr_0.6.2      timeDate_3010.98   timeSeries_3010.97
[26] tools_3.0.2        whisker_0.3-2      yaml_2.1.7 

Code:

    library(quantstrat)
library(PerformanceAnalytics)

ttz<-Sys.getenv('TZ')
#Sys.setenv(TZ='UTC')
Sys.setenv(TZ='GMT')

currency("USD")
symbols <- c("XLY", "XLP", "XLE", "AGG", "IVV")
stock(symbols, currency="USD")

# get data for the symbols
getSymbols(symbols, from="2005-01-01", to="2012-12-31")

# create an xts object of monthly adjusted close prices
symbols.close <- monthlyPrices(symbols)

# create an xts object of the symbol ranks
sym.rank <- applyRank(x=symbols.close, rankFun=ave3ROC, n=c(2, 4, 6))

# this is an important step in naming the columns, e.g. XLY.Rank
# the "Rank" column is used as the trade signal (similar to an indicator)
# in the qstratRank function
colnames(sym.rank) <- gsub(".Close", ".Rank", colnames(sym.rank))

# ensure the order of order symbols is equal to the order of columns 
# in symbols.close
stopifnot(all.equal(gsub(".Close", "", colnames(symbols.close)), symbols))

# bind the rank column to the appropriate symbol market data
# loop through symbols, convert the data to monthly and cbind the data
# to the rank
for(i in 1:length(symbols)) {
  x <- get(symbols[i])
  x <- to.weekly(x,indexAt='lastof',drop.time=TRUE)
  indexFormat(x) <- '%Y-%m-%d'
  colnames(x) <- gsub("x",symbols[i],colnames(x))
  x <- cbind(x, sym.rank[,i])
  assign(symbols[i],x)
}

bt <- qstratRank(symbols=symbols, init.equity=100000, top.N=2,
                 max.size=1000, max.levels=1)

Functions:

    qstratRank <- function(symbols, init.equity=100000, top.N=1, 
                           max.size=1000, max.levels=1) {
      # The qstratRank function uses the quantstrat framework to backtest a
      # ranking or relative strength strategy
      #
      # args
      # symbols     : character vector of symbols
      # init.equity : initial equity
      # top.N       : trade the top N ranked assets
      # max.size    : maximum position size
      # max.levels  : maximum levels to scale in a trade
      # max.size and max.levels are passed to addPosLimit
      #
      # return value
      # returns a list: end.eq, returns, book, stats

      # remove variables
      suppressWarnings(rm("order_book.Rank", pos=.strategy))
      suppressWarnings(rm("account.Rank", "portfolio.Rank", pos=.blotter))
      suppressWarnings(rm("account.st", "port.st", "stock.str", "stratRank",
                          "initDate", "initEq", 'start_t', 'end_t'))


      # set initial variables
      initDate <- "1900-01-01"
      initEq <- init.equity
      port.st <- "Rank"
      account.st <- "Rank"

      # trade the top "N" ranked symbols
      N <- top.N

      # initialize quantstrat objects
      initPortf(port.st, symbols=symbols, initDate=initDate)
      initAcct(account.st, portfolios=port.st, initDate=initDate,initEq=initEq)
      initOrders(portfolio=port.st, initDate=initDate)

      # initialize a strategy object
      stratRank <- strategy("Rank")

      # there are two signals
      # the first signal is when Rank is less than or equal to N
      # (i.e. trades the #1 ranked symbol if N=1)
      stratRank <- add.signal(strategy=stratRank, name="sigThreshold", 
                              arguments=list(threshold=N, column="Rank", 
                                             relationship="lte", cross=FALSE), 
                              label="Rank.lte.N")

      # the second signal is when Rank is greter than or equal to N
      # (i.e. trades the #1 ranked symbol if N=1)
      stratRank <- add.signal(strategy=stratRank, name="sigThreshold", 
                              arguments=list(threshold=N, column="Rank", 
                                             relationship="gt", cross=FALSE), 
                              label="Rank.gt.N")

      # add buy rule
      stratRank <- add.rule(strategy=stratRank, name='ruleSignal', 
                            arguments = list(sigcol="Rank.lte.N", sigval=TRUE, 
                                             orderqty=max.size, ordertype='market', 
                                             orderside='long', pricemethod='market', 
                                             replace=FALSE, osFUN=osMaxPos,TxnFees=pennyPerShare), 
                            type='enter', path.dep=TRUE)

      # add exit rule
      stratRank <- add.rule(strategy = stratRank, name='ruleSignal', 
                            arguments = list(sigcol="Rank.gt.N", sigval=TRUE, 
                                             orderqty='all', ordertype='market', 
                                             orderside='long', pricemethod='market', 
                                             replace=FALSE,TxnFees=pennyPerShare), 
                            type='exit', path.dep=TRUE)

      #set max position size and levels
      for(symbol in symbols){ addPosLimit(port.st, symbol, initDate, max.size, max.levels) }

      print("setup completed")

      # apply the strategy to the portfolio
      start_t <- Sys.time()
      out <- try(applyStrategy(strategy=stratRank, portfolios=port.st))
      end_t <- Sys.time()
      print(end_t-start_t)

      # update Portfolio
      start_t <- Sys.time()
      updatePortf(Portfolio=port.st, Dates=paste('::', as.Date(Sys.time()), sep=''))
      end_t <- Sys.time()
      print("trade blotter portfolio update:")
      print(end_t - start_t)

      # update account
      updateAcct(account.st)

      # update ending equity
      updateEndEq(account.st)

      # get ending equity
      eq <- getEndEq(account.st, Sys.Date()) + initEq

      # view order book to confirm trades
      order.book <- getOrderBook(port.st)

      # get trade statistics
      stats <- tradeStats(port.st)

      # portfolio returns
      ret1 <- PortfReturns(port.st)
      ret1$total <- rowSums(ret1, na.rm=TRUE)

      return(list(end.eq=eq, returns=ret1, book=order.book, stats=stats))
    }



   ##### monthlyAd function #####
monthlyAd <- function(x){
  # Converts daily data to monthly and returns only the monthly close 
  # Note: only used with Yahoo Finance data so far
  # Thanks to Joshua Ulrich for the Monthly Ad function
  # 
  # args:
  #   x = daily price data from Yahoo Finance
  #
  # Returns:
  #   xts object with the monthly adjusted close prices

  sym <- sub("\\..*$", "", names(x)[1])
  Cl(to.weekly(x, indexAt = 'lastof', drop.time = TRUE, name = sym)) ##ändrade från to.monthly och till Close from Adjusted
}

##### monthlyReturns function #####
monthlyReturns <- function(symbols) {
  # The function takes a character vector of symbols loaded into
  # the environment and returns an xts object of simple returns
  # Currently this is only for prepping monthly data

  # symbols : character vector of symbols

  ROC(x = monthlyPrices(symbols), n = 1, type = "discrete", na.pad = TRUE)
}

    ##### monthlyPrices function #####
    monthlyPrices <- function(symbols) {
      # The function takes a character vector of symbols loaded into
      # the environment and returns an xts object of Adjusted close prices
      # Currently this is only for prepping monthly data

      # symbols         : character vector of symbols
      # list.sym        : list of symbols with market data

      list.sym <- list()
      for(i in 1:length(symbols)) {
        list.sym[[symbols[i]]] <- get(symbols[i])
      }

      do.call(merge, lapply(list.sym, monthlyAd))
    }







        # RankningFunktioner ------------------------------------------------------
        # Functions for ways to rank assets based on rate of change
        # TODO - add functions to rank based on other factors

        # The functions defined below depend on functions in the xts and TTR packages
        # library(TTR)

        ##### applyRank #####
        applyRank <- function(x, rankFun, ...) {
          # symbols : character vector of symbols
          # rankFun : function that returns the rank
          # rankFun should be ave3ROC, weightAve3ROC, strengthROC, strengthAve3ROC,
          # etfReplayRank, or strengthSMA.
          # x       : xts object of prices
          # ...     : arguments to rankFun

          FUN <- match.fun(rankFun)
          FUN(x, ...)
        }

        ##### symbolRank #####
        symbolRank <- function(symbols, rank.obj) {
          # loop through symbols
          # convert the market data to monthly periodicity 
          # cbind the appropriate column from rank.obj to the market data
          # makes the assumption that the order symbols and rank.obj are equal

          # symbols  : character vector of symbols
          # rank.obj : xts object of ranks of each symbol

          for(i in 1:length(symbols)) {
            x <- get(symbols[i])
            x <- to.monthly(x,indexAt='lastof',drop.time=TRUE)
            indexFormat(x) <- '%Y-%m-%d'
            colnames(x) <- gsub("x", symbols[i], colnames(x))
            x <- cbind(x, rank.obj[,i])
            assign(symbols[i],x)
          }
        }

        ##### rowRank #####
        rowRank <- function(x){
          # Computes the rank of an xts object of ranking factors
          # ranking factors are the factors that are ranked (i.e. asset returns)
          #
          #  x : xts object of ranking factors
          #
          #   Returns an xts object with ranks
          #   For ranking asset returns, the asset with the greatest return
          #   receives a  rank of 1

          as.xts(t(apply(-x, 1, rank, na.last = "keep")))
        }

        #Use the supplied TTR::ROC function for a straight ROC computation

        ##### ave3ROC #####
        ave3ROC <- function(x, n=c(1, 3, 6)){
          # Computes the average rate of change based on averaging 3 periods
          #
          #  x   : xts object of prices
          #  n   : vector of periods to use n = (period1, period2, period3)
          #  ave : xts object of asset rate of change by averaging 3 periods

          roc1 <- ROC(x, n = n[1], type = "discrete")
          roc2 <- ROC(x, n = n[2], type = "discrete")
          roc3 <- ROC(x, n = n[3], type = "discrete")
          ave <- (roc1 + roc2 + roc3)/3
          rowRank(ave)
        }

回答1:


I finally had a little bit of time to look into this. The problem is that TxnFees needs to be a character string containing the name of a function not an actual function itself. I'm going to make this more clear in the documentation for addOrder.

In the meantime, your example works for me if I change the lines below:

# add buy rule
stratRank <- add.rule(strategy=stratRank, name='ruleSignal', 
  arguments = list(sigcol="Rank.lte.N", sigval=TRUE, 
                   orderqty=max.size, ordertype='market', 
                   orderside='long', pricemethod='market', 
                   replace=FALSE, osFUN=osMaxPos,TxnFees="pennyPerShare"), 
  type='enter', path.dep=TRUE)

# add exit rule
stratRank <- add.rule(strategy = stratRank, name='ruleSignal', 
  arguments = list(sigcol="Rank.gt.N", sigval=TRUE, 
                   orderqty='all', ordertype='market', 
                   orderside='long', pricemethod='market', 
                   replace=FALSE,TxnFees="pennyPerShare"), 
  type='exit', path.dep=TRUE)


来源:https://stackoverflow.com/questions/26716128/pennypershare-quantstrat-not-working

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!