【问题标题】:Optimizing Quanstrat MACD with apply.paramset returns error使用 apply.paramset 优化 Quantstrat MACD 返回错误
【发布时间】:2016-03-22 21:51:08
【问题描述】:

我正在尝试测试一些涉及数字货币的交易策略。其中一种策略涉及 MACD 交叉,但我想优化 nSlownFast 参数。

这是一个可重现的示例(运行):

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'

上面运行得非常好。但是,我想将 nFastnSlow 参数更改为 MACD() 函数:

## 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)

这给了我以下错误,我不确定如何调试:

error calling combine function:
<simpleError in fun(result.1, result.2, result.3, result.4, result.5, result.6, ... attempt to select less than one element>

我做错了什么? FWIW,我使用的是 Ubuntu 12.04/14.04。任何帮助深表感谢。谢谢!!

【问题讨论】:

  • 请不要cross post。或者,至少,告诉人们您正在交叉发帖,这样他们就不会浪费时间回答在他们不关注的论坛上已经回答的问题。
  • @JoshuaUlrich 对此感到抱歉。以后我会记下来的。

标签: r quantmod quantstrat domc blotter


【解决方案1】:

好的,我想通了。

add.distribution 函数中的component.label 参数需要与add.indicator 中的label 参数匹配。因此,在这种特殊情况下,我将add.indicator 更改为:

add.indicator(strategy.name, name = "MACD", arguments = list(x=quote(Cl(mktdata))), label='MACD')

然后把我的add.distribution改成:

add.distribution(strategy.name,
                 paramset.label = 'optEMA',
                 component.type = 'indicator',
                 component.label = 'MACD',
                 variable = list(nFast = 60:80),
                 label = 'NFAST')

add.distribution(strategy.name,
                 paramset.label = 'optEMA',
                 component.type = 'indicator',
                 component.label = 'MACD',
                 variable = list(nSlow = 180:200),
                 label = 'NSLOW')

它运行。把这个留在这里,以防其他人遇到类似的错误。

【讨论】:

    【解决方案2】:

    这段代码我或多或少有同样的问题

    ################################# MACD PARAMETERS OPTIMIZATION
    
    .fastMA = (30:60)
    .slowMA = (50:80)
    .nsamples = 10
    
    # Paramset
    
    add.distribution(volStrat,
                     paramset.label = 'optEMA',
                     component.type = 'indicator',
                     component.label = 'macd.out', 
                     variable = list(n = .fastMA),
                     label = 'nFAST'
    )
    
    add.distribution(volStrat,
                     paramset.label = 'optEMA',
                     component.type = 'indicator',
                     component.label = 'macd.out', 
                     variable = list(n = .slowMA),
                     label = 'nSLOW'
    )
    
    add.distribution.constraint(volStrat,
                                paramset.label = 'optEMA',
                                distribution.label.1 = 'nFAST',
                                distribution.label.2 = 'nSLOW',
                                operator = '<',
                                label = 'optEMA'
    )
    
    results <- apply.paramset(volStrat, 
                              paramset.label = 'optEMA', 
                              portfolio = portfolio2.st, 
                              account = account.st, 
                              nsamples = .nsamples, 
                              verbose = TRUE)
    
    stats <- results$tradeStats
    
    print(stats)
    

    出现的错误是:

    Error in must.be.paramset(strategy, paramset.label) : 
      optEMA : no such paramset in strategy VIXSPY_MACD
    

    我真的不明白如何选择paramset.label 值。

    非常感谢

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-12-31
      • 2018-03-06
      • 2018-07-13
      • 1970-01-01
      • 2020-10-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多