[R-SIG-Finance] Optimizing Quanstrat MACD with apply.paramset returns combine error

Joshua Ulrich josh.m.ulrich at gmail.com
Wed Mar 23 01:21:06 CET 2016


Please don't cross post: http://stackoverflow.com/q/36165926/271616

Or, at the very minimum, tell people you're cross posting so they
don't waste their time answering a question that's already been
answered on a forum they don't follow.

On Tue, Mar 22, 2016 at 5:05 PM, Ray Bao <theraybao at gmail.com> wrote:
> I am trying to test some trading strategies involving digital
> currency. One such strategy involves MACD crossovers, but I would like
> to optimize the nSlow & nFast parameters. Here's a reproducible
> example (which runs):
>
> ###########################################################################################
>
> library(httr)
> library(plyr)
> library(quantstrat)
> library(PerformanceAnalytics)
> library(IKTrading)  # install_github("IlyaKipnis/IKTrading")
>
> poloniex.ohlc.30m <-
> content(GET("https://poloniex.com/public?command=returnChartData&currencyPair=BTC_ETH&start=1439010600&end=9999999999&period=1800"))
>  # https://poloniex.com/support/api/
> ETHBTC.30m <- ldply(poloniex.ohlc.30m, data.frame)  # Convert OHLCV to
> data.frame
> ETHBTC.30m$date <- as.POSIXct(ETHBTC.30m$date, origin = "1970-01-01")
>
> # Create 'xts' object:
> ethbtc.30m.xts <- xts(ETHBTC.30m[, 2:8], order.by = ETHBTC.30m$date)
> # is.OHLCV(ETHBTC.30m)
>
> # Rebuild empty environments if RStudio's "Clear All" has been used:
> if (!exists('.instrument')) .instrument <- new.env()
> if (!exists('.blotter')) .blotter <- new.env()
> if (!exists('.strategy')) .strategy <- new.env()
>
> ## Optional: Subset timeframe
> ETHBTC <- ethbtc.30m.xts[,c("open", "high", "low", "close",
> "volume")]["2016-02-01::"]
>
> ## Define instruments
> currency(c('BTC', 'ETH'))  # ls_currencies()
> exchange_rate('ETHBTC', currency = 'BTC', counter_currency = 'ETH',
> tick_size = 0.00001)
>
> initDate = '2016-02-01'
> initBTC <- 100
> initETH <- 0
>
> portfolio.name <- "crypto"
> account.name <- "poloniex"
> strategy.name <- "accumulator"
> symbols <- "ETHBTC"
>
> ## To rerun
> rm.strat(portfolio.name)
> rm.strat(account.name)
> rm.strat(strategy.name)
>
> ## Initialize Portfolio, Account, and Orderbook
> initPortf(name = portfolio.name, symbols = symbols, initPosQty = 0,
> initDate = initDate, currency = "BTC")  # getPortfolio(portfolio.name)
> initAcct(name = account.name, portfolios = portfolio.name, initDate =
> initDate, initEq = 0, currency = "BTC")  # getAccount(account.name)
> initOrders(portfolio = portfolio.name, symbols = symbols, initDate =
> initDate)  # getOrderBook(portfolio.name)
> strategy(strategy.name, store = TRUE)  # summary(getStrategy(strategy.name))
>
> ## Indicators
> # Parameters
> .nFast = 60 # 90
> .nSlow = 130
> .nSig = 45 # 75
>
> add.indicator(strategy.name, name = "MACD", arguments =
> list(x=quote(Cl(mktdata))), label=NULL)
>
> ## Signals
> # See Also: applySignals add.indicator link{add.rule} sigComparison
> sigCrossover sigFormula sigPeak sigThreshold
> # MACD
> add.signal(strategy.name, "sigCrossover",
>            arguments = list(columns = c("macd.MACD.ind",
> "signal.MACD.ind"), relationship = "gt"),
>            label = 'longEntry')
> add.signal(strategy.name, "sigCrossover",
>            arguments = list(columns = c("signal.MACD.ind",
> "macd.MACD.ind"), relationship = "gt"),
>            label = 'signal.gt.macd')
> add.signal(strategy.name, "sigThreshold",
>            arguments = list(column = "macd.MACD.ind", threshold = 0,
> relationship = "gte"),
>            label = 'macd.gte.threshold')
> add.signal(strategy.name, "sigAND",
>            arguments=list(columns=c('signal.gt.macd',
> 'macd.gte.threshold'), cross=FALSE),
>            label="longExit")
>
> # Order sizing
> osFixedDollar <- function(timestamp, orderqty, portfolio, symbol, ruletype, ...)
> {
>   ClosePrice <- as.numeric(Cl(mktdata[timestamp,]))
>   orderqty <- round(tradeSize/ClosePrice,-2)
>   return(orderqty)
> }
> tradeSize <- initBTC/2
>
> ## Rules
> # Entry
> add.rule(strategy.name,name='ruleSignal',
>          arguments = list(sigcol="longEntry",
>                           sigval=TRUE,
>                           orderqty=1000,
>                           ordertype='market',
>                           orderside='long',
>                           osFUN='osFixedDollar'),
>          type='enter',
>          label='EnterLONG',
>          storefun=FALSE)
>
> # Exit
> add.rule(strategy.name,name='ruleSignal',
>          arguments = list(sigcol="longExit",
>                           sigval=TRUE,
>                           orderqty='all',
>                           ordertype='market',
>                           orderside='long',
>                           osFUN='osFixedDollar'),
>          type='exit',
>          label='ExitLONG',
>          storefun=FALSE)
>
> ## Run it
> applyStrategy(strategy.name,
>               portfolios=portfolio.name,
>               parameters=list(nFast = .nFast, nSlow = .nSlow, nSig =
> .nSig, maType = 'EMA'),
>               verbose=TRUE)
>
> updatePortf(Portfolio=portfolio.name,Dates=paste('::',as.Date(Sys.time()),sep=''))
> updateAcct(account.name)
> updateEndEq(account.name)
>
> ## Evaluate
> t(tradeStats(portfolio.name))
> getTxns(portfolio.name, Symbol = 'ETHBTC')
> perTradeStats(portfolio.name, "ETHBTC")
>
> chart.Posn(Portfolio=portfolio.name,Symbol=symbols, type = "line",
> log.scale = T)
> plot(add_Vo())
> plot(add_MACD(fast=.nFast, slow=.nSlow, signal=.nSig,maType="EMA"))  #
> nFast = 60, nSlow = 180, nSig = 40, maType = 'EMA'
>
> ###########################################################################################
>
> The above runs perfectly-fine. However, I want to vary the nFast and
> nSlow parameters to the MACD() function:
>
> ## Parameter distribution testing
> add.distribution(strategy.name,
>                  paramset.label = 'optEMA',
>                  component.type = 'indicator',
>                  component.label = 'nFast',
>                  variable = list(nFast = 60:80),
>                  label = 'NFAST')
>
> add.distribution(strategy.name,
>                  paramset.label = 'optEMA',
>                  component.type = 'indicator',
>                  component.label = 'nSlow',
>                  variable = list(nFast = 180:200),
>                  label = 'NSLOW')
>
> library(doMC)
> registerDoMC(cores=detectCores())
>
> results <- apply.paramset(strategy.name, paramset.label = "optEMA",
> portfolio=portfolio.name, account=account.name, nsamples=0)
>
> ###########################################################################################
>
> This gives me the following error, which I'm not sure how to debug:
>
> error calling combine function:
> <simpleError in fun(result.1, result.2, result.3, result.4, result.5,
> result.6, ... result.439, result.440, result.441): attempt to select
> less than one element>
>
> What am I doing wrong? FWIW, I am using Ubuntu 12.04/14.04. Any help
> is much appreciated. Thanks!!
>
> --
> Ray Bao
> T: 925.272.9226
> M: 510.292.3438
> iamraybao.com
>
> _______________________________________________
> R-SIG-Finance at r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-sig-finance
> -- Subscriber-posting only. If you want to post, subscribe first.
> -- Also note that this is not the r-help list where general R questions should go.



-- 
Joshua Ulrich  |  about.me/joshuaulrich
FOSS Trading  |  www.fosstrading.com
R/Finance 2016 | www.rinfinance.com



More information about the R-SIG-Finance mailing list